什么是安全策略

内容安全策略 (CSP) 是一个额外的安全层,用于检测并削弱某些特定类型的攻击,包括跨站脚本 (XSS) 和数据注入攻击等。无论是数据盗取、网站内容污染还是散发恶意软件,这些攻击都是主要的手段。

CSP的功能

跨站脚本攻击

CSP通过指定有效域,即浏览器认可的可执行脚本的有效来源,使服务器管理者有能力减少或消除XSS攻击所依赖的载体。一个CSP兼容的浏览器将会仅执行从白名单域获取到的脚本文件,忽略所有的其他脚本 (包括内联脚本和HTML的事件处理属性)。

数据包嗅探攻击

除限制可以加载内容的域,服务器还可指明哪种协议允许使用;比如 (从理想化的安全角度来说),服务器可指定所有内容必须通过HTTPS加载。一个完整的数据安全传输策略不仅强制使用HTTPS进行数据传输,也为所有的cookie标记安全标识 cookies with the secure flag,并且提供自动的重定向使得HTTP页面导向HTTPS版本。网站也可以使用Strict-Transport-Security HTTP头部确保连接它的浏览器只使用加密通道。

怎么使用CSP

配置内容安全策略涉及到添加Content-Security-PolicyHTTP头部到一个页面,并配置相应的值,以控制用户代理(浏览器等)可以为该页面获取哪些资源。比如一个可以上传文件和显示图片页面,应该允许图片来自任何地方,但限制表单的action属性只可以赋值为指定的端点。一个经过恰当设计的内容安全策略应该可以有效的保护页面免受跨站脚本攻击。

怎么测试CSP

为降低部署成本,CSP可以部署为报告(report-only)模式。在此模式下,CSP策略不是强制性的,但是任何违规行为将会报告给一个指定的URI地址。此外,一个报告模式的头部可以用来测试一个修订后的未来将应用的策略而不用实际部署它。

可以用Content-Security-Policy-Report-OnlyHTTP头部来指定你的策略,像这样:

Content-Security-Policy-Report-Only: policy

如果Content-Security-Policy-Report-Only头部和Content-Security-Policy同时出现在一个响应中,两个策略均有效。在Content-Security-Policy头部中指定的策略有强制性 ,而Content-Security-Policy-Report-Only中的策略仅产生报告而不具有强制性。

启用违例报告

默认情况下,违规报告并不会发送。为启用发送违规报告,需要指定 report-uri 策略指令,并提供至少一个URI地址去递交报告:

Content-Security-Policy: default-src 'self'; report-uri /csp-report

CSP应用实例

比如我们设置策略为

Content-Security-Policy: default-src 'none'; style-src cdn.example.com; report-uri /csp-reports

上面的意思是不允许当前源站的静态资源(包括ico,js,css等),只允许加载cdn.example.com的样式,将错误信息上报到/csp-reports请求

下面是测试结果可以看出,请求源站的静态资源会被block掉,无法加载

上面设置report-uri /csp-report后,浏览器会针对每次违例请求通过post请求发给服务器,请求体如下

{
  "csp-report": {
    "document-uri": "http://localhost:8080/",
    "referrer": "",
    "violated-directive": "style-src-elem",
    "effective-directive": "style-src-elem",
    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /report",
    "disposition": "enforce",
    "blocked-uri": "http://localhost:8080/public/dist/style/index.cebb39b158b702281852.css",
    "line-number": 8,
    "source-file": "http://localhost:8080/",
    "status-code": 200,
    "script-sample": ""
  }
}

请求体的字段解释如下

document-uri 发生违规的文档的URI
referrer 违规发生处的文档引用(地址)
blocked-uri 被CSP阻止的资源URI。如果被阻止的URI来自不同的源而非文档URI,那么被阻止的资源URI会被删减,仅保留协议,主机和端口号
violated-directive 违反的策略名称
original-policy 在 Content-Security-Policy HTTP 头部中指明的原始策略

纯前端使用

CSP可以通过设置html文档响应头部来控制,也可以通过前端meta标签来控制,简单的用法如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
    <script
        src="https://code.jquery.com/jquery-3.5.1.js"
        integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
        crossorigin="anonymous"></script>
</head>
<body>
</body>
</html>