【问题标题】:Copy to clipboard as plain text以纯文本形式复制到剪贴板
【发布时间】:2014-08-02 21:05:54
【问题描述】:

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

它复制带有格式的文本。如何以没有格式的纯文本复制文本?

【问题讨论】:

    标签: javascript google-chrome text google-chrome-extension copy-paste


    【解决方案1】:

    您的问题代码包含一个常见的安全问题,称为XSS。由于您采用不受信任的输入并将其分配给 .innerHTML,因此您允许攻击者在您的文档上下文中插入任意 HTML。

    幸运的是,攻击者无法在您的扩展程序上下文中运行脚本,因为扩展程序的默认 Content security policy 禁止内联脚本。正是因为这种情况,Chrome 扩展程序才会强制执行此 CSP,以防止 XSS 漏洞。

    将 HTML 转换为文本的正确方法是通过DOMParser API。以下两个函数显示了如何将文本复制为文本,或者将您的案例 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 解释为换行符,请使用非标准(但在 Chrome 中支持).innerText 属性而不是 .textContent

    以下是使用您的问题中的executeCopy 函数如何滥用 XSS 的众多示例中的两个:

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

    【讨论】:

    • 谢谢。你能解释一下攻击者是如何触发executeCopy的吗?
    • 为了测试,您只需将代码粘贴到后台页面的控制台中即可。对于攻击者:我假设输入可以由他们控制,因为消息来自内容脚本,大概是从网页中获取 HTML。
    • 攻击者是否能够在不首先编辑活动页面的 HTML 的情况下调用 executeCopy
    • @JosephMornin 攻击者永远能够直接调用executeCopy,因为它只能由你的扩展调用。我所做 知道该函数是从内容脚本中调用的,大概 直接从页面中使用 HTML。在您的问题中,您 没有 说明了该函数的使用方式,因此我必须做出一些最坏情况的假设才能切合实际。此外,您还没有指定问题中的“文本”是文本还是 HTML,这就是为什么我的答案的第一个修订版假定您确实想要复制文本而不是 HTML(待续......)
    • 我仍然认为你想复制文本而不是 HTML,因为如果你想在 contentscript 中复制页面的内容,那么你可以在 content scipt 中使用 element.textContent 而不是 @ 987654337@。请注意,由于您的问题缺乏细节,我不得不做出许多假设。下次您提出问题时,请提供问题的完整背景,这样读者就不必试图读懂您的想法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    • 2014-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多