web-dev-qa-db-ja.com

プレーンテキストとしてクリップボードにコピー

Chrome拡張機能のbackground.jsでこのコードを使用して、テキストをユーザーのクリップボードにコピーしています。

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);
}

テキストをフォーマットしてコピーします。書式なしのプレーンテキストでテキストをコピーするにはどうすればよいですか?

12
Joe Mornin

質問のコードには、 [〜#〜] xss [〜#〜] と呼ばれる一般的なセキュリティの問題が含まれています。信頼できない入力を受け取って.innerHTMLに割り当てるため、攻撃者がドキュメントのコンテキストに任意のHTMLを挿入できるようになります。

幸い、拡張機能のデフォルト コンテンツセキュリティポリシー はインラインスクリプトを禁止しているため、攻撃者は拡張機能のコンテキストでスクリプトを実行できません。このCSPは、XSSの脆弱性を防ぐために、まさにこのような状況のためにChrome拡張機能で適用されます。

HTMLをテキストに変換するcorrect方法は、 DOMParser APIを使用することです。次の2つの関数は、テキストをテキストとしてコピーする方法、または場合によってはHTMLをテキストとしてコピーする方法を示しています。

// 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);
}

.textContentはHTMLタグを完全に無視することに注意してください。 <br>sを改行として解釈する場合は、.innerTextの代わりに非標準(ただしChromeでサポートされている).textContentプロパティを使用します。

質問のexecuteCopy関数を使用してXSSが悪用される可能性のある多くの例のうちの2つを次に示します。

// 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>');
15
Rob W