Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy to clipboard as plain text

I'm using this code in background.js in a Chrome extension to copy text to the user's clipboard:

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
        if (request.command == "copy") {
            executeCopy(request.text);
            sendResponse({farewell: "copy request received"});
        }
    }
);

function executeCopy(text){
    var copyDiv = document.createElement('div');
    copyDiv.contentEditable = true;
    document.body.appendChild(copyDiv);
    copyDiv.innerHTML = text;
    copyDiv.unselectable = "off";
    copyDiv.focus();
    document.execCommand('SelectAll');
    document.execCommand("Copy", false, null);
    document.body.removeChild(copyDiv);
}

It copies the text with formatting. How can I copy the text in plain text with no formatting?

like image 483
Joe Mornin Avatar asked Aug 02 '14 21:08

Joe Mornin


People also ask

How do you copy and paste as plain text?

Use Ctrl + Alt + V (or Cmd + Alt + V on a Mac) to open the Paste Special window. Here, select Unformatted Text to paste in plain text. Finally, if you'd like, you can set the default paste option in Word to always paste in plain text.

How do I remove formatting when copying and pasting?

Copy and paste-without-formatting on a PC: Ctrl-C, Ctrl-Shift-V. Normal copy and paste on a Mac: Cmd-C, Cmd-V. Copy and paste-without-formatting on a Mac: Cmd-C, Cmd-Opt-Shift-V.

What does Paste as plain text mean?

When you paste content as plain text, most formatting will be removed. You can add formatting such as bold and italics using the buttons or keyboard commands in the Rich-Text Editor.


1 Answers

Your question's code contains a common security issue known as XSS. Because you take untrusted input and assign it to .innerHTML, you're allowing attackers to insert arbitrary HTML in the context of your document.

Fortunately, attackers cannot run scripts in the context of your extension because the extension's default Content security policy forbid inline scripts. This CSP is enforced in Chrome extensions exactly because of situations like this, to prevent XSS vulnerabilities.

The correct way to convert HTML to text is via the DOMParser API. The following two functions show how to copy text as text, or for your case HTML as text:

// Copy text as text
function executeCopy(text) {
    var input = document.createElement('textarea');
    document.body.appendChild(input);
    input.value = text;
    input.focus();
    input.select();
    document.execCommand('Copy');
    input.remove();
}

// Copy HTML as text (without HTML tags)
function executeCopy2(html) {
    var doc = new DOMParser().parseFromString(html, 'text/html');
    var text = doc.body.textContent;
    return executeCopy(text);
}

Note that .textContent completely ignores HTML tags. If you want to interpret <br>s as line breaks, use the non-standard (but supported in Chrome) .innerText property instead of .textContent.

Here are two of the many examples of how XSS could be abused using the executeCopy function from your question:

// This does not only copy "Text", but also trigger a network request
// to example.com!
executeCopy('<img src="http://example.com/">Text');

// If you step through with a debugger, this will show an "alert" dialog
// (an arbitrary script supplied by the attacker!!)
debugger;
executeCopy('<iframe src="data:text/html,<script>alert(/XXS-ed!/);<\/script>"></iframe>');
like image 155
Rob W Avatar answered Sep 20 '22 12:09

Rob W