背景
在Manifest V3中,谷歌对CSP策略的限制变得更加严格。例如,不允许使用unsafe-inline
指令,这避免扩展执行远程代码,然而,这也意味着注入到页面中隔离环境的Content Scripts受到了扩展CSP策略的约束。因此,当页面中的链接包含内联的事件处理器/javascript:
伪协议时,如果尝试在Content Scripts中点击链接,将发生错误,如下图所示:
在Content Scripts中,操纵页面元素是一个非常常见的需求,如何在保证扩展合法的情况下,正常进行按钮的点击,便变得十分重要。
解决方案
chrome.scripting介绍
为了达成这一目的,Chrome在ManifestV3扩展中提供了动态注入脚本的能力(chrome.scripting)。该接口允许我们将扩展中存在的js文件或文件中的特定函数注入到指定页面中。
以上是一段示例代码,executeScript
方法提供了向指定页面注入脚本的能力(类似于通过Manifest文件注入Content Scripts),该方法包含了名为world的参数,可以设置为ISOLATED和MAIN。通过这个参数,开发者可以自由选择将脚本注入到isolated环境还是main环境中。
isolated环境就是Content Scripts默认注入的环境,在此环境下,Content Scripts能够操作页面、访问页面顶层变量,但原始页面无法读取Content Scripts的内容,并且Content Scripts受到扩展CSP策略的限制。
相反地,被注入到main环境的脚本受到原始页面CSP策略的限制。此外,原始页面可以访问Content Scripts中的变量。
实现方式
有了executeScript
方法,我们就可以尝试通过在main环境中执行click
来绕过扩展的CSP策略限制。
大概的实现方式如下:
- 在isolated环境下的Content Stript中向background发起点击链接的请求,并传递元素选择器
- background收到点击链接的请求后,向页面注入一个main环境的脚本用于点击对应的链接