如何在IIS 10中避免JavaScript注入并保留自身内联脚本运行
解决IIS中CSP配置:允许自身内联JS同时阻止注入脚本
这个问题其实是CSP(内容安全策略)里最常见的痛点之一——既要保留自己的内联/页面内JS正常运行,又要杜绝第三方(包括用户通过浏览器检查器注入的)内联脚本执行。你之前的两种配置要么太松(用'unsafe-inline'允许所有内联脚本)要么太严(完全禁止内联导致自己的代码失效),核心问题是'unsafe-inline'是"一刀切"的指令,所以得用CSP提供的更精细的控制方式:脚本哈希值或Nonce(随机一次性令牌)。
方法一:使用脚本哈希值(适合固定不变的内联脚本)
如果你的内联JS内容是写死的、不会频繁修改的(比如页面初始化的固定逻辑),可以给这些脚本生成加密哈希,然后把哈希加入CSP的script-src指令中。这样只有哈希匹配的内联脚本会被允许执行,用户注入的alert('ok')这类脚本哈希肯定不匹配,会直接被拦截。
操作步骤:
- 复制你的内联JS代码(要完全一致,包括空格、换行符),比如:
initPageLayout(); bindNavigationEvents(); - 生成该脚本的SHA-256(或SHA-384/SHA-512)哈希值。你可以用本地工具生成,比如Node.js命令行:
node -e "console.log(require('crypto').createHash('sha256').update('initPageLayout();bindNavigationEvents();').digest('base64'))" - 在IIS的
web.config中配置CSP响应头,把生成的哈希值按'sha256-生成的哈希字符串'格式加到script-src里:<system.webServer> <httpProtocol> <customHeaders> <add name="Content-Security-Policy" value="default-src 'self' site.com; style-src 'self' site.com 'unsafe-inline'; script-src 'self' site.com 'sha256-abcdef1234567890abcdef1234567890abcdef1234567890abcdef'"/> </customHeaders> </httpProtocol> </system.webServer>
注意事项:
- 如果有多个独立的内联脚本,需要把每个脚本的哈希都加到
script-src中。 - 脚本内容哪怕修改一个空格或换行,哈希都会失效,所以只适合固定不变的脚本。
方法二:使用Nonce(适合动态内联脚本或频繁更新的页面)
Nonce是一个每次请求都随机生成的唯一字符串,你需要把它同时加到CSP响应头和对应的内联<script>标签里。只有携带正确Nonce的脚本才会被允许执行,用户注入的脚本没有这个专属令牌,自然无法运行。
操作步骤:
- 在后端代码(比如ASP.NET)中生成随机Nonce:
// 在页面加载时生成无连字符的唯一GUID作为Nonce string nonce = Guid.NewGuid().ToString("N"); // 将Nonce加入CSP响应头 Response.Headers.Add("Content-Security-Policy", $"default-src 'self' site.com; style-src 'self' site.com 'unsafe-inline'; script-src 'self' site.com 'nonce-{nonce}'"); // 把Nonce传递给前端页面(以MVC模式为例) ViewBag.Nonce = nonce; - 在前端的内联
<script>标签中添加nonce属性,值为后端生成的Nonce:<script nonce="@ViewBag.Nonce"> // 你的动态内联JS代码,比如依赖后端数据的逻辑 const currentUser = @Html.Raw(Json.Encode(ViewBag.CurrentUser)); initUserSession(currentUser); </script>
注意事项:
- Nonce必须是随机、不可预测的,且每次请求都要重新生成,绝对不能复用固定值,否则会有安全风险。
- 外部脚本文件只要来自
'self'或site.com,依然会被正常加载,不受Nonce影响。
为什么这两种方法比'unsafe-inline'安全?
'unsafe-inline'会允许任何内联脚本执行,包括用户通过浏览器检查器注入的恶意代码。而哈希和Nonce是白名单机制:只有你明确指定的(哈希匹配或带正确Nonce)内联脚本才能运行,完全杜绝了未授权的内联脚本执行。
测试验证
配置完成后,你可以打开浏览器控制台尝试注入alert('ok'),应该会看到CSP报错提示脚本被阻止;同时你自己的内联脚本应该能正常运行。如果遇到问题,可以检查:
- 哈希值是否和脚本内容完全匹配
- Nonce是否在响应头和script标签中完全一致
- IIS是否正确配置了自定义响应头(避免重复的CSP头)
内容的提问来源于stack exchange,提问作者Hamid Reza
相关产品推荐
相关产品推荐

