如何从(ny)网页到Chrome扩展进行安全通信

How to do secure communication from a(ny) web page to a Chrome extension

本文关键字:扩展 Chrome 通信 安全 网页 ny      更新时间:2023-09-26

我想在网页和Chrome扩展之间进行安全通信。经过相当多的检查和黑客攻击,这似乎至少不是微不足道的,如果不是完全不可能的话。

我想从网页中的(一些JavaScript(发送扩展的后台页面(当它运行时(的消息(注意,网页启动通信,这是非常不典型的!(。我向扩展发送一些凭据(因此需要一个安全通道!(,然后如果这些凭据是有效的(由后台页面中的逻辑确定(,那么后台页面应该返回一些(JSON(值,然后网页可以显示这些值。

我已经有了一些代码,可以检查当前的浏览器是否是Chrome,以及用户是否安装了所述扩展(以及一些用户界面,如果不是,他/她可以安装它,等等…(

我还使用window.postMessage运行了一些通信。它将一条消息从网页脚本发布到扩展内容脚本,然后从那里传播到后台页面。然而,这是不安全的,因为这个MDN页面引用:

建议postMessage暂时不要用于与chrome:页面通信;使用不同的方法(例如打开窗口时使用查询字符串(与Chrome窗口进行通信。

(此评论位于页面底部附近的Using window.postMessage in extensions部分(

这似乎是一个合理的建议,因为似乎没有办法排除使用postMessage发送的数据可能会被浏览器中的另一个窗口/选项卡截获,而不是到达扩展。因此,这个漏洞可以被利用。

在我的情况下,使用MDN文章所建议的查询字符串是不可能的,因为后台页面是在一开始加载的(还没有URL参数(。

我的推理是否合理/清晰?有没有Chrome扩展专家有什么建议?

注意:建议使用externally_connectable docs,但如文档中所述,指定网站的matches部分只允许子域通配符,而问题域要求允许网站的动态列表,而该列表不能在扩展的清单中硬编码。

您需要使用"externally_connectable"通信方法。

如果您的扩展声明它想与某个域通信(您需要在清单中列出该域(,那么chrome.runtime.sendMessage将暴露在页面上下文中。

然后,在您的页面上,您可以通过以下方式传递信息:

var extensionID = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
if(chrome && chrome.runtime && chrome.runtime.sendMessage) {
  // There is an extension that declared this page in externally_connectable
  chrome.runtime.sendMessage(extensionID, data);
} else {
  // Either this is not Chrome, or no extension wants to listen
}

在扩展端,您将获得chrome.runtime.onMessageExternal事件中的数据。

如果您愿意,您可以与chrome.runtime.connect建立双向长期连接。

Chrome将确保只有具有给定ID的扩展才能收到您的消息。这将保护您免受其他网页的窃听,但请注意,任何扩展都有足够的能力连接/修改页面的脚本并获取数据。


由于该问题已更新为"无固定站点列表"要求,因此有另一种解决方案。内容脚本可以使用DOM事件与页面脚本进行通信。它们不会泄漏到其他页面中,但同样,这不能防止其他扩展。

请参阅此答案以了解更多详细信息;我将在这里留下一个代码片段作为示例。

// Content script
//Listen for the event
window.addEventListener("PassToBackground", function(evt) {
  chrome.runtime.sendMessage(evt.detail);
}, false);
// Page context
var message = {/* whatever */};
var event = new CustomEvent("PassToBackground", {detail: message});
window.dispatchEvent(event);