Content Security Policy (CSP) 是什么?为什么它能抵御 XSS 攻击?

什么是CSP?

CSP是由单词 Content Security Policy 的首单词组成,CSP旨在减少(注意这里是减少而不是消灭)跨站脚本攻击。

CSP是一种由开发者定义的安全性政策性申明,通过CSP所约束的的规责指定可信的内容来源(这里的内容可以指脚本、图片、iframe、fton、style等等可能的远程的资源)。通过CSP协定,让WEB处于一个安全的运行环境中。
示例:

1.只允许本站资源

Content-Security-Policy: default-src ‘self’

2.允许本站的资源以及任意位置的图片以及http://trustedscripts.example.com下的脚本。

Content-Security-Policy: default-src ‘self’; img-src *;

script-src http://trustedscripts.example.com
更多关于CSP的介绍可以参考W3C的相关文档: dvcs.w3.org/hg/content-

一部分中文翻译:CSP - HTML5 Chinese Interest Group Wiki

CSP的讨论

CSP的出现可以一定程度上的减少XSS的攻击,但不一定意味着XSS的消失。


挺久之前过了一遍CSP的安全策略,很多人把它喻为XSS攻击的终结者,因为这种策略不再像传统只靠各种正则和特征匹配来识别跨站攻击Payload,而是直接从协议层把一些存在安全隐患的用法默认给干掉了,把同源同域更发挥到了极致。把之前整理的内容发到这里吧。

  1. CSP策略在默认的情况下是不允许使用data URIs资源的,如果要使用,那么需要显示的指定,比如:img-src 'self' data:
  2. script-src:在处理脚本资源的时候设置"unsafe-inline"可以阻止内联Js代码的执行。使用unsafe-eval开关可以禁止eval,setTimeout,setInterval函数的执行。
  3. object-src:控制embed,code,archive applet等对象。
  4. style-src:会控制样式表@import和rel时所引入的URI资源,设置unsafe-inline规则可以是浏览器拒绝解析内部样式和内联样式定义。并不会阻止链入外部样式表。
  5. img-src:可以控制图片资源的连接,包括img标签的src属性,以及CSS3中的url()和image()方法,以及link标签中的href属性(当rel设置成与图像相关的值,比如HTML支持的icon)
  6. media-src:控制媒体类型的外部链入资源,如video, audio, source, 和track标签的src属性。
  7. frame-src:控制内嵌框架包含的外部页面连接:iframe or a frame。
  8. font-src:控制CSS中的@font-face
  9. connect-src:控制XMLHttpRequest中的open(),WebSocket,EventSource
  10. inline script和eval类型函数(包括eval、setInterval、setTimeout和new Function())是不被执行的。另外data URIs也是默认不允许使用的,XBL,只允许通过chrome:和resource:形式uri请求的XBL,其它的比如在CSS中通过-moz-binding来指定的XBL则不允许被执行。

关于Bypass:

  1. 通过CRLF相应头分裂注入来BypassCSP需要将新的相应头插入到原来的CSP下面,在处理相同名字的Http头时候,少数浏览器是根据第一次出现的来设置,大部分则是根据最后一次出现的同名Http头来设置。这种属于伪绕过。
  2. 请参考kuza55大神的Bypassing Content-Security-Policy,讲了很多通过第三方前端框架的特性实现绕过的case,基本覆盖全了。

综述:
个人愚见,首先CSP是可以在一定程度上提高XSS的攻击难度的,甚至杜绝XSS,前提是CSP策略用的好。还要考虑CSP能否普及,因为CSP在提供安全性的同时也提高了前端逻辑的复杂度,很多资源需要调整,类似QQ,新浪,搜狐这样的站群,想通过合适的CSP同时提高安全性和易用性是很难的。


好像没人提到nonce。。占个坑回来答内容安全策略 (CSP) 上面已经有很多人讲了,CSP本身也可以比较好的解决XSS的问题,但事实上,XSS的重灾区常常在Inline JavaScript,CSP1.1不能解决这个问题。CSP2开始支持nonce-来解决Inline JavaScript的问题,在HTTP Header中声明一个随机字符串,在HTML中的JavaScript标签上带了nonce属性,nonce的值和Header指定的一致才会执行对应的JavaScript代码。讲的比较抽象,举个例子吧:

<!DOCTYPE html>
<html>
<title>Hello CSP2</title>
 
<script nonce="aaaa">document.write("222222222<br>");</script>
 
<script nonce="bbbb">document.write("333333333<br>");</script>
 
</html>

注意上面的代码里 script标签带有nonce属性。这时候我们在header中声明csp的nonce属性(各种语言都可以做到)

Content-security-policy: 'nonce-aaaa';

这时候我们运行页面,发现页面中只打印了222222222,通过注入nonce,从根本上杜绝了inline-script造成xss的可能。当然,csp的实现成本还是不小的,它需要解析网站内部的script标签,可能会带来一些额外的模板引擎的性能成本。
参考资料:Content Security Policy Level 2: Content Security Policy
CSP (Content Security Policy)


Content Secruity Policy

CSP 是在2008年由 Mozilla 的 Sterne 提出的浏览器安全框架

  • 被设计为一个完整的框架来防御 XSS 和 CSRF 攻击
  • 通常也可以用来控制 app 和扩展的权限

CSP 允许开发者覆写(SOP)每个 document 的权限

  • Server 在 header 中定义规则

ff6f49f30947e53c63795274487f2de2_r

 

CSP 让开发者提高了对 XSS 攻击的防御能力, 但也存在一些问题.

  • 难部署(如要改动左右inline scripts)
  • 对 Origin 的定义不够细致
  • Binary 安全

DEMO

数据库里存了一个用户输入的信息, 简单的弹窗JS.(外链JS也是同理)

cript>alert('I was stored by an attacker.');</script>

无CSP保护
ce7ea5aee4ae82e5a3320c6e809cdb7e_r

有CSP保护
708e2854a7d4b818d85f3f3078f216d2_r

还没有评论,快来抢沙发!

发表评论

  • 😉
  • 😐
  • 😡
  • 😈
  • 🙂
  • 😯
  • 🙁
  • 🙄
  • 😛
  • 😳
  • 😮
  • emoji-mrgree
  • 😆
  • 💡
  • 😀
  • 👿
  • 😥
  • 😎
  • ➡
  • 😕
  • ❓
  • ❗
  • 68 queries in 0.400 seconds