如何修复网站Content-Security-Policy中的'unsafe-eval'问题?
解决CSP启用后依赖eval()的JS库失效问题
一、先排查当前CSP配置的冗余与冲突
你的现有配置存在一些无效或冗余规则,可能干扰功能正常运行:
frame-src中的'unsafe-inline'和'unsafe-eval'无意义,frame-src仅控制允许加载的框架源,框架内的脚本规则由自身CSP或主页面script-src管控,建议移除这两个值。style-src里的*已经覆盖所有源,保留fonts.googleapis.com和自身域名即可,去掉*能让规则更严格。- 既然已经使用nonce,理论上可移除
script-src和style-src中的'unsafe-inline',但如果存在未添加nonce的内联脚本/样式,可暂时保留,后续逐步替换。
调整后的基础配置示例:
header( "Content-Security-Policy: upgrade-insecure-requests; default-src 'self'; " . "object-src 'none'; ". "style-src 'self' 'unsafe-inline' fonts.googleapis.com " . str_replace('www','', $_SERVER['HTTP_HOST']) . "; ". "script-src 'self' 'nonce-" . $_SESSION['token_csp'] . "' 'unsafe-inline' 'unsafe-eval' https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ https://www.googletagmanager.com/gtag/; " . "font-src 'self' fonts.gstatic.com ; " . "frame-src 'self' data: https://www.google.com/ *.youtube.com *.youtube-nocookie.com; " . "img-src https: data:; " . "base-uri 'self'; ". "form-action 'self'; ". "child-src 'self'; ". "media-src *.google.com *.youtube.com; ". "frame-ancestors 'none'; ". "connect-src *; " );
二、处理依赖eval()的JS库问题
1. 替换为无eval()的库版本
多数主流JS库的新版本已移除对eval()的依赖:
- jQuery:升级到3.5+版本,官方已大幅减少eval的使用,改用更安全的实现方式。
- 日期/时间选择器:替换为原生JS实现的插件(如flatpickr),或使用jQuery UI datepicker的最新分支(部分版本已移除eval)。
- thickbox/buttons:改用现代替代方案,比如用原生模态框替换thickbox,用CSS+原生JS实现按钮交互逻辑。
2. 用脚本哈希替代'unsafe-eval'(无法替换库时)
如果暂时无法替换依赖库,可为每个含eval()的JS文件计算SHA-256/SHA-384/SHA-512哈希,添加到script-src中替代'unsafe-eval':
- 计算哈希:用命令行工具生成,示例:
openssl dgst -sha256 -binary your-script.js | base64 - 配置示例:
script-src 'self' 'nonce-xxx' 'sha256-abcdef...' ...
注意:这种方式需要维护所有依赖文件的哈希,文件更新后需重新计算,适合文件变动频率低的场景。
3. 开启CSP报告模式精准排查
先将CSP设为report-only模式,只收集违规报告而不拦截资源,可精准定位哪些文件依赖eval(),以及是否有其他被拦截的资源:
header( "Content-Security-Policy-Report-Only: upgrade-insecure-requests; default-src 'self'; " . // 其余规则与之前一致,添加报告端点 "report-uri https://your-report-endpoint.com; " );
收集报告后,针对性处理每个违规项,比如替换对应库、添加哈希或调整规则。
4. 确保nonce正确应用
当前配置使用了nonce,需确保页面中所有内联脚本都添加nonce="xxx"属性:
- 内联脚本示例:
<script nonce="<?php echo $_SESSION['token_csp']; ?>">// 内联代码</script> - 注意:nonce应每次请求重新生成,不要固定存在session中(否则会降低安全性),建议将nonce存在请求上下文而非session。
三、分步推进严格CSP
不要一次性启用最严格规则,分阶段调整:
- 先保留
'unsafe-inline'和'unsafe-eval',确保网站正常运行,开启报告模式收集违规信息。 - 逐步替换依赖eval()的库,每替换一批,就移除
'unsafe-eval'或添加对应哈希。 - 所有内联脚本添加nonce后,移除
'unsafe-inline'。 - 最后优化其他规则,比如收紧
connect-src到必要源,而非使用*。
内容的提问来源于stack exchange,提问作者Divyesh
相关产品推荐
相关产品推荐

