CSP

头像
helbing
    阅读 3 分钟

    CSP(Content Security Policy),内容安全策略,是浏览器厂商为了缓解很大一部分潜在的 XSS 问题而引入的一个安全层,用来取代之前的 X-XSS-Protection。两者相比,绝大多数浏览器已经支持 CSP,因而 X-XSS-Protection 已经被废弃了,作为了解可以看 MDN 文档

    使用

    CSP 策略可以在两处地方添加,一处是 HTML 页面中的 meta 标签,另一处是在 HTTP Response Header 中

    Meta 标签

    
    <meta http-equiv="content-security-policy" content="script-src 'self'; object-src 'self'">
    
    <meta http-equiv="content-security-policy-report-only" content="script-src 'self'; object-src 'self'; report-uri 'https://test.com/report'">

    content-security-policycontent-security-policy-report-only 的区别在于 content-security-policy 会限制不符合 CSP 策略的行为,而 content-security-policy-report-only 不会进行限制,而是报告不符合 CSP 策略的行为

    HTTP Response Header

    和 Meta 标签添加 CSP 策略的方式其实差不多,只是策略是写在 HTTP Response Header 中而已。实际上更加推荐是把 CSP 策略写在 HTTP Response Header 的,这样更加方便于维护。这里以 Caddy 为例

    header / Content-Security-Policy "script-src 'self'; object-src 'self'"
    
    header / Content-Security-Policy-Report-Only "script-src 'self'; object-src 'self'; report-uri 'https://test.com/report'"

    策略

    • base-uri:用于限制 <base> 元素中显示的网址
    • child-src:用于列出适用于工作线程和嵌入的帧内容的网址。例如:child-src https://youtube.com 将启用来自 YouTube(而非其他来源)的嵌入视频
    • connect-src:用于限制可(通过 XHR,WebSockets,Fetch 和 EventSource)连接的来源。
    • font-src:用于指定可提供网页字体的来源
    • form-action:限制 <form> 提交的地址
    • frame-ancestors:指定可嵌入当前页面的来源。此指令适用于 <frame><iframe><embed><applet>
    • img-src:限制允许加载图像的来源
    • media-src:限制允许传输视频和音频的来源
    • object-src:限制 Flash 或其他插件的 src
    • plugin-types:限制页面可以调用的插件种类
    • report-urireport-to:上报数据地址,report-uri 被废弃,但是不是全部浏览器都支持 report-to,所以建议两个都写
    • style-src:限制样式表来源

    您可以通过指定一个 default-src 指令来设置默认合法的来源。不过下面这些策略不受 default-src 的影响

    • base-uri
    • form-action
    • frame-ancestors
    • plugin-types
    • report-uri
    • sandbox

    来源

    来源这块不单单可以填写实际的域名,还有一些关键词可以使用

    • none:不限制来源
    • self:与当前来源(而不是其子域)匹配
    • unsafe-inline:允许使用内联 JavaScript 和 CSS
    • unsafe-eval:允许使用类似 eval 的 text-to-JavaScript 机制

    Nonces 和 Hashes

    在 CSP1 中,inline 资源要么全部允许,要么全部不允许。在实际开发中影响还是比较大的,虽然禁用 inline 资源确实能很有效的防御 XSS。所以 CSP2 引入了 Nonces 和 Hashes

    Nonces 用于指定 inline 资源的序号(base64 编码后的随机数),只有指定了序号的 inline 资源来可以被执行

    Content-Security-Policy: script-src 'nonce-1'
    <script nonce="1">alert(0);</script>

    Hashes 则是将 inline 资源直接做摘要签名,签名规则与 Subresource Integrity 一致,支持的算法有 SHA-256,SHA-512 等。同样摘要签名一样要做 base64 加密

    echo -n 'alert(0);' | openssl dgst -sha256 -binary | openssl enc -base64 -A
    Content-Security-Policy: script-src 'sha256-d3ii1Pel57UO62xosCMNgTaZJhJa87Gd/X6e7UdlEU8='
    <script>alert(0);</script>

    Nonces 方案使用起来比较简单,而 Hashes 方案相对安全许多

    report

    如果设置了 `report-uri` 或 `report-to`,那么当有不符合策略的行为出现时,就会往设置的 URI 地址 发送一个 POST 请求,具体数据大概如下所示

    {
    
        "csp-report": {
    
            "document-uri": "http://127.0.0.1:9000/",
    
            "referrer": "",
    
            "violated-directive": "font-src",
    
            "effective-directive": "font-src",
    
            "original-policy": "default-src 'self' ; report-uri http://127.0.0.1:9000/report.php",
    
            "disposition": "enforce",
    
            "blocked-uri": "data",
    
            "status-code": 200,
    
            "script-sample": ""
    
        }
    }

    资料


    helbing
    131 声望7 粉丝

    下一篇 »
    XSS