web项目中,如何让我们的页面能够只加载我允许的域名的资源呢?那就配一个白名单,CSP就是这么来的。

what

CSP,内容安全策略(Content Security Policy)

用于检测并削弱某些特定类型的攻击,包括跨站脚本 (XSS) 和数据注入攻击等。

使用

CSP其实就是一个白名单策略,允许的域才能加载,其他一律拒绝。

使用CSP有两种模式:meta设置 & http响应头设置

meta设置

<meta http-equiv="Content-Security-Policy" content="CSP指令">
复制代码

http响应头设置

response: {
    Content-Security-Policy: "CSP指令"
}
复制代码

规则

懂得怎么使用之后,我们就来看CSP指令怎么写。

/**
 * 指令
 */
default-src // 默认规则,某些类型没有特定规则时,则使用默认规则
script-src // javascript规则
style-src // 样式规则
img-src // 图片规则
connect-src // 链接规则,如ajax、websocket
font-src // 字体规则
object-src // 标签引入flash插件的规则
media-src // <video> <audio>引入多媒体的规则
frame-src // iframe加载规则
report-uri // 请求策略不被允许时,提交日志的地址
复制代码
/**
 * 指令值
 */
 空 // 不做限制
 'none' // 不允许任何内容
 'self' // 允许同源(协议/域名/端口)
 data // data协议,如base64的图片
 binnie.qq.com // 指定域名
 *.qq.com // 指定某个域
 https://binnie.qq.com // 指定协议域名
 https: // 允许https
 'unsafe-inline' // 允许加载inline资源
 'unsafe-eval' // 允许动态js,如eval()
复制代码

举个例子,下面这条CSP规则,就指明来script和style只能是同源的或*.qq.com的,如果加载其他源的地址均会被拒绝。

Content-Security-Policy: script-src 'self' *.qq.com; style-src 'self' *.qq.com;
复制代码

实践

meta模式



http响应头模式



结果,这里只截里meta模式的错误,效果是一样的。不允许的资源就会被浏览器拒绝。



注意

CSP规则无论是响应头模式还是meta模式,如果在http的情况下,就有可能被运营商劫持修改(就是一些乱七八糟的广告),所以最好使用CSP+https来确保项目的安全性。

由于CSP规则是白名单,不在白名单内的资源就会加载失败,所以编辑规则的时候要确认不影响系统的正常使用,以免引起其他bug。

写在最后

在项目开发过程中,安全无疑是最重要的,当然,没有绝对的安全,所以我们能做的,就是让系统尽可能的安全。

说不定哪天又出来新的攻击呢?