移动端内联脚本被 CSP 阻止如何排查?检查 script 标签的 nonce 属性
当浏览器控制台显示内联脚本被阻止时,通常是因为 CSP 策略禁止了未经过哈希或 nonce 验证的脚本执行。
确认控制台报错信息
在移动端浏览器中打开网页,按 F12 或使用开发者工具切换到 Console(控制台)面板。查找包含“An attempt to execute inline scripts has been blocked”或“Refused to execute inline script”的红色报错信息。这些日志明确指出页面安全策略拦截了直接写在 HTML 标签内部的 JavaScript 代码,而非外部加载的文件。
如果控制台显示“Tried to send report to invalid URI”,说明 CSP 配置了报告 URI 但地址无效,导致违规信息无法发送。此时需要检查 HTTP 响应头中的 Content-Security-Policy-Report-Only 或 Content-Security-Policy 设置,确保 report-uri 或 report-to 指向有效的 HTTP 或 HTTPS 地址,否则无法通过报告机制排查具体违规原因。
检查 script 标签的 nonce 属性
在 HTML 源码中定位被拦截的 script 标签,确认其是否包含 nonce 属性。nonce 属性是一个一次性使用的随机字符串,必须与服务器生成的 CSP 头部中的值完全匹配才能执行。如果 script 标签没有 nonce,或者 nonce 值与头部不一致,浏览器将视为违规并阻止执行。
确保服务器在生成 CSP 头部时,nonce 值是动态生成的且与页面中所有允许执行的 script 标签一一对应。如果使用了 nonce-source,必须确保 script 标签的 nonce 属性值与头部中的值严格一致,否则会触发“Ignoring source... within script-src: nonce-source specified”的警告,导致脚本无法加载。
验证 CSP 头部配置
使用浏览器开发者工具的 Network(网络)面板,筛选响应头,找到 Content-Security-Policy 头部。检查头部中是否包含了 script-src 指令,并确认是否指定了 nonce-source。如果头部仅包含 default-src 或其他指令,而没有明确允许 script,内联脚本同样会被拦截。
如果头部配置了 report-only 策略,浏览器会允许脚本执行但发送违规报告。此时需要对比 report-only 头部与实际生效的头部,确认是否需要将策略升级为 enforce 模式。同时注意,如果头部中存在 'strict-dynamic' 关键字,且没有有效的 nonce 或 hash,可能会阻止所有脚本的加载,需谨慎配置。
排查其他潜在冲突
检查是否存在多个 CSP 头部或冲突的指令。如果页面同时设置了 Content-Security-Policy 和 Content-Security-Policy-Report-Only,且策略不一致,可能导致脚本加载异常。确保只使用一个策略头部,并根据需要调整其内容。
确认 script 标签内没有包含 eval() 等不安全的函数调用。即使配置了 nonce,如果代码中使用了 eval(),浏览器也可能根据 CSP 的其他限制(如 unsafe-eval)再次拦截。此外,确保没有重复的 script-src 指令,否则后出现的指令会覆盖前面的设置,导致部分脚本被忽略。
资料与延伸阅读
你可以通过以下原始资料核对文中概念,并继续深入阅读。