chrome extension 谷歌插件 content scripts 跨域限制(但可以发送)的设计理念

背景

随着 chrome 浏览器安全机制的升级,原来的 V2 版本中一些有的权限被移除了,尤其明显的就是 content script 的跨域逻辑处理,这里将对跨域调研的详细过程做一个总结

官方文档

隐藏的比较深,放在 In depth: security 中

https://developer.chrome.com/docs/extensions/mv3/xhr/

大概讲了,自动 chrome73 和 chrome83 就开始进行限制了,在此之前没做过限制

注意一个细节:manifest 中的 Content-Security-Policy 要表达的是针对于 popop.html 和 option.html,以及 content script 中请求的域名安全问题,避免插件被攻击用的,如果想解决 web.whatsapp.com facebook.com 等网站不让在 console 私自载入 jquery 脚本,则必须拦截 url 请求,并将 response.header.content-security-policy 中的限制 host 改为* 即可

一个启发点

// 扩展本身的json竟然也可以用ajax进行请求,这种叫同源请求是没有问题的
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = handleStateChange; // Implemented elsewhere.
xhr.open("GET", chrome.extension.getURL('/config_resources/config.json'), true);
xhr.send();

官方说明这种改造的原因:

Content scripts pose a challenge for Site Isolation, because they run in the same Chrome renderer process as the web page they operate on. This means that the renderer process must be allowed to fetch data from any origin for which the extension has permissions, which in many cases is all origins. In such cases, Site Isolation would have less effectiveness when content scripts are present, because a compromised renderer process could hijack the content scripts and request (and thus leak) any data from the origins listed in the extension. (Thankfully, this is not a problem for Spectre attacks, which cannot take control of content scripts. It is a problem if an attacker can exploit a security bug in Chrome's renderer process, though, allowing the attacker to issue arbitrary requests as if they came from the content script.)

翻译成中文的意思是:

content scripts 和 page 使用的是同一个渲染进程,本来渲染进程中,是严格限制未经服务端允许的跨域请求,且很完美,但若为了兼容 content script 可以直接通过渲染进程发出请求,那渲染进程就得有一种能力放开所有的请求 host 的拦截,而这样能力一旦被黑客利用,那浏览器就很危险了。

content scripts 可以跨域请求吗?

可以,条件有两点:

  1. 服务端允许跨域请求,插件端可以通过 ajax,axios,fetch 以跨域模式进行请求;

  2. 如果遇到注入的网站采用的是 https 协议,也必须用 https 协议,用 http 会被自动转为 https,造成请求出错

为什么跨域会如此严重?

这个很少有人说的很明白,举个例子如果 A 网站,已经探明了 BCD 网站的请求接口,包括 http 和 websocket 等,那就意味着,A 网站开发者,可以在 A 站中对 BCD 的接口发起请求,而浏览器是自动将 cookie 携带上去发出,这就意味着 A 网站的开发者就可以完全监听 BCD 站的各种信息,甚至 D 网站的有些数据来源于客户端,而 A 可以通过修改用户提交接口的传入参数来恶意搞垮 D 网站,这种行为都不能发生,所以跨域的危害性很大。

为何说 content script 通过 sendMessage 不能直接传 url 呢?

因为恶意网站 A 可以诱导一个拥有“host_permissions”:<all_urls> 权限且该插件拥有大量有户的情 插件 E,网站 A 就可以绕开跨域问题,然后肆无忌惮获取插件 E 用户的所有网站的信息了,这个想想还挺可怕的。

content scripts 替代方案

  1.  通过 background 进行中转处理;

// background service worker 代码
chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
      if (request.contentScriptQuery == 'fetchUrl') {
        // WARNING: SECURITY PROBLEM - a malicious web page may abuse
        // the message handler to get access to arbitrary cross-origin
        // resources.
        fetch(request.url)
            .then(response => response.text())
            .then(text => sendResponse(text))
            .catch(error => ...)
        return true;  // Will respond asynchronously.
      }
    });

// content scripts 代码
chrome.runtime.sendMessage(
    {contentScriptQuery: 'fetchUrl',
     url: 'https://another-site.com/price-query?itemId=' +
              encodeURIComponent(request.itemId)},
    response => parsePrice(response.text()));

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Chrome扩展content-scripts请求跨域的问题,可以通过在manifest.json文件中添加"permissions"和"web_accessible_resources"字段来解决。具体步骤如下: 1. 在manifest.json文件中添加"permissions"字段,用于声明扩展需要访问的权限。例如: ``` { "name": "My Extension", "version": "1.0", "manifest_version": 2, "permissions": [ "http://www.example.com/*" ], "content_scripts": [ { "matches": ["http://www.example.com/*"], "js": ["content_script.js"] } ] } ``` 以上代码中,"http://www.example.com/*"表示扩展需要访问的域名,"content_scripts"表示扩展需要注入的脚本。 2. 在manifest.json文件中添加"web_accessible_resources"字段,用于声明扩展需要访问的资源。例如: ``` { "name": "My Extension", "version": "1.0", "manifest_version": 2, "permissions": [ "http://www.example.com/*" ], "content_scripts": [ { "matches": ["http://www.example.com/*"], "js": ["content_script.js"] } ], "web_accessible_resources": [ "http://www.example.com/*" ] } ``` 以上代码中,"http://www.example.com/*"表示扩展需要访问的资源。 3. 在content_script.js文件中使用XMLHttpRequest或fetch等API发送跨域请求,代码示例如下: ``` fetch('http://www.example.com/api/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error)); ``` 以上代码中,fetch方法用于发送跨域请求,并且在响应中获取数据。 需要注意的是,如果要在content-scripts中使用cookie等认证信息,需要在manifest.json文件中添加"permissions"字段,并使用XMLHttpRequest或fetch等API发送带有cookie的跨域请求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

森叶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值