JustZix 如何在 CSP 严格的页面上注入代码
有些页面的 Content-Security-Policy 严格到不会执行任何不是它作者写的脚本。可 JustZix 仍然能把你的 JS 注入进去,并把 Output Console 挂到页面的 console.log 上。本文解释这是怎么做到的 —— 以及为什么第一个版本做不到。
CSP 是什么、为什么它碍事
Content-Security-Policy 是一个 HTTP 头,页面用它声明脚本可以从哪里加载。一个典型的严格策略是 script-src 'self' —— 「只执行来自我自己域名的脚本」。这样的策略会阻止内联的 <script>:如果你往 DOM 里注入一个 <script>代码...</script> 标签,浏览器不会执行它。GitHub、银行仪表盘和许多企业网站就是这样工作的。
第一种做法 —— 以及一次回归
Output Console 钩子的一个早期版本(v2.13.72-73)正是通过加到 <head> 里的一个内联 <script> 来注入代码。在普通页面上它有效。在带 script-src 'self' 的页面上浏览器静默拒绝那个脚本 —— 钩子从未挂上,Output Console 保持为空。这是一次回归:一个在「演示里」有效的功能,恰恰在开发者最需要它的地方失败了。
修复 —— chrome.scripting.executeScript
解决方案(v2.13.74)不再注入一个 <script> 标签。相反,扩展的 service worker 调用 chrome.scripting.executeScript。这就是关键区别:这个脚本以扩展的权限运行,而不是页面级别。页面的 CSP 不适用于它 —— 浏览器把它当作用户在安装时同意过的、可信扩展的代码。
MAIN world 对 ISOLATED world
扩展的 content script 默认活在一个「隔离世界」(ISOLATED)里 —— 它们有自己的 window,与页面分开。这很安全,但当你想挂到页面真正的 console.log 或碰它的全局变量时就没用了。
所以钩子落在 MAIN world 里 —— 页面代码所活的同一个 JavaScript 上下文。在那里它能包装 console.log/warn/error、挂上 error 和 unhandledrejection 监听器,并精确看到页面所看到的。
世界之间的一座桥 —— postMessage
MAIN world 里的钩子捕获日志,但 Output Console 窗口本身是由 ISOLATED world 里的一个 content script 渲染的。两个世界不共享变量 —— 需要一座桥。那座桥是 window.postMessage:
- MAIN world 的钩子拦截一条
console.log条目。 - 它序列化参数并用一个带标签的载荷调用
window.postMessage。 - ISOLATED 的 content script 监听
message,按标签过滤,并把条目渲染到 Output Console 窗口里。
postMessage 是少数几个穿越世界边界的通道之一 —— 而且它不违反 CSP 就做到这点,因为它不是脚本执行,只是消息传递。
这在实践中意味着什么
Output Console 和 JS 注入在那些经典内联脚本伎俩会失败的页面上有效 —— GitHub、银行仪表盘、带硬 CSP 的企业内网。你什么都不用配置;扩展自己选这条路。
限制 —— CSP 仍然不会允许什么
- 从你的代码加载外部脚本。如果你注入的 JS 试图加一个
<script src="https://cdn...">,那个新标签仍然受页面 CSP 约束。 - fetch 到被阻止的域名。
connect-src指令仍然限制页面代码能向哪里发请求。 - 这不是安全绕过。它之所以有效,是因为用户有意识地安装了扩展并授予了它权限 —— 这是你授予的特权,不是一个漏洞。
v3.2.0 更新 —— 规则、动作和 TEMP 窗口也一样
上面的机制说的是 Output Console 钩子 —— 扩展如何监听页面的 console.log。执行你的 JS 规则、动作和 TEMP JS 窗口是另一条路径 —— 而且它过去也只在 CSP 允许 'unsafe-eval' 的页面上才能工作。在 v3.2.0 中我们把同样的「分层策略」移植到了第二条路径上:尝试顺序是 chrome.userScripts.execute → new Function → <script src="blob:…">。现在规则、动作和 JS pane / JS Console 即使在 Facebook 上也能运行(通过 blob 回退),在完全 CSP 严格的站点上也能运行(通过 userScripts,在一次性「允许用户脚本」选择加入之后)。完整介绍:JustZix JavaScript 规则现在在 Facebook、X 和 GitHub 上也能用。
另见
- Output Console 捕获错误 —— 钩子看到什么
- Output Console —— 日志落地的窗口
- window.JZ 辅助函数 —— 程序化 API
安装 JustZix —— 即便页面说「不」,也能注入代码。
为这篇文章评分
暂无评分 — 成为第一个。