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);
}
テキストをフォーマットしてコピーします。書式なしのプレーンテキストでテキストをコピーするにはどうすればよいですか?
質問のコードには、 [〜#〜] 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>');