内容安全策略(CSP)
翻译
原文:https://portswigger.net/web-security/cross-site-scripting/content-security-policy
- name: 翻译
desc: 原文:https://portswigger.net/web-security/cross-site-scripting/content-security-policy
bgColor: '#F0DFB1'
textColor: 'green'
2
3
4
# 内容安全策略(CSP)
# 1什么是CSP(内容安全策略)?
CSP 是一种浏览器安全机制,旨在缓解 XSS 和其他一些攻击。它的工作原理是限制页面可以加载的资源(如脚本和图像),并限制当前页面 是否可以被其他页面载入。
若要启用 CSP,需要在响应中包含一个名为Content-Security-Policy
的 HTTP 响应标头,其值应包含策略。策略本身由一个或多个指令组成,用分号分隔。
# 2使用CSP缓解XSS攻击
以下指令只允许从 与页面本身相同的源 (opens new window)加载脚本:
script-src 'self'
以下指令只允许从特定域加载脚本:
script-src https://scripts.normal-website.com
当允许 来自外部域的脚本 时应小心。如果攻击者有任何方法,可以控制从外部域提供的内容,那么他们就可能发起攻击。例如,不使用内容分发网络(CDN)的公共 URL,例如ajax.googleapis.com
,该域名不应被信任,因为第三方可以随时将内容传输到其域中。
除了将特定域列入白名单之外,内容安全策略还提供了另外两种 指定受信任资源的方法:随机数和哈希:
- CSP 指令可以指定一个 nonce(随机值),并且在加载脚本的标签中必须使用相同的值。如果值不匹配,则脚本将不会执行。为了有效地实现控件,当页面每次加载时,都必须安全地生成随机数,并且不能被攻击者猜测到数值。
- CSP 指令可以指定受信任脚本内容的哈希。如果实际脚本的哈希值 与 指令中指定的值不匹配,则脚本将不会执行。如果脚本的内容发生了更改,那么你当然需要更新指令中的指定哈希值。
CSP 阻止script
等资源是很常见的。但是,许多 CSP 都允许图像请求。这意味着你可以使用img
元素向外部服务器发出请求,例如泄露 CSRF (opens new window) 令牌。
某些浏览器(例如 Chrome)具有内置的悬挂标记 (opens new window)缓解功能,可阻止包含某些字符的请求,例如原始的、未编码的新行或尖括号。
某些策略的限制性更强,可阻止所有形式的外部请求。但是,你仍然可以通过引发一些用户交互来绕过这些限制 (opens new window)。要绕过这种形式的策略,你需要注入一个 HTML 元素,当单击注入的元素时,该元素会存储自身包含的所有内容,并将其发送到外部服务器。
- name: 实验室-专家
desc: 内容安全策略-反射型XSS-非常严格的CSP保护-悬挂标记攻击 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/cross-site-scripting/content-security-policy/lab-very-strict-csp-with-dangling-markup-attack
bgColor: '#001350'
textColor: '#d112fe'
2
3
4
5
6
# 3使用CSP缓解悬挂标记攻击
以下指令只允许从 与页面本身相同的源加载图像:
img-src 'self'
以下指令只允许从特定域加载图像:
img-src https://images.normal-website.com
请注意,这些策略将防止一些悬挂标记攻击,因为无需用户交互即可捕获数据的一种简单方法是使用img
标记。但是,它不能阻止其他攻击,例如那些带有悬挂href
属性的锚点标签注入攻击。
# 4通过策略注入绕过CSP
你可能会遇到这样一个网站,它将用户输入反馈到实际策略中,很可能位于report-uri
指令中。如果站点反馈了可控参数,则可以插入一个分号,以添加你自己的 CSP 指令。通常,此report-uri
指令是列表中的最后一个指令。这意味着你需要覆盖现有指令,才能利用此漏洞并绕过策略。
通常,你无法覆盖现有的script-src
指令。但是,Chrome 最近引入了script-src-elem
指令,它允许你控制script
元素,但不能控制事件。至关重要的是,这个新指令允许你覆盖现有的script-src
指令。利用这些知识,你应该能够解决以下实验。
- name: 实验室-专家
desc: 内容安全策略-反射型XSS-绕过CSP保护 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/cross-site-scripting/content-security-policy/lab-csp-bypass
bgColor: '#001350'
textColor: '#d112fe'
2
3
4
5
6
# 5使用CSP防止点击劫持
以下指令只允许 同一来源的其他页面 对当前页面进行 frame 处理:
frame-ancestors 'self'
以下指令将完全阻止 frame 处理:
frame-ancestors 'none'
使用内容安全策略来防止点击劫持 (opens new window),比使用X-Frame-Options
标头更灵活,因为你可以指定多个域并使用通配符。例如:
frame-ancestors 'self' https://normal-website.com https://*.robust-website.com
CSP 还会验证父级 frame 层次结构中的每个 frame,而X-Frame-Options
仅验证顶级 frame。
建议使用 CSP 来防范点击劫持攻击。你还可以将其与X-Frame-Options
标头结合使用,以在不支持 CSP 的旧浏览器(如 Internet Explorer)上提供保护。