Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

内容安全策略 #2

Open
sevenCon opened this issue Jun 7, 2019 · 0 comments
Open

内容安全策略 #2

sevenCon opened this issue Jun 7, 2019 · 0 comments

Comments

@sevenCon
Copy link
Owner

sevenCon commented Jun 7, 2019

内容安全策略

什么是内容安全策略?

内容安全策略 , Content-Security-Policy, 简称CSP, 是浏览器为了防止cross-site-script 攻击的一种手段, 方式是通过定义脚本的uri的whitelist. 只允许whitelist的链接加载并运行, 如css, script, object等.

怎么开启CSP?

CSP, 在浏览器是默认关闭的, 需要手动开启, 开启的方式有2种,
一种是通过html的meta元信息

<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none';">

另一种是通过http返回的请求头中定义

Content-Security-Policy:script-src 'self'; object-src 'none';

所以:

  • Content-Security-Policy: ; 的定义方式,多个指令需要用';' 进行隔开
  • 'self' 一定要是单引号,不能是双引号

CSP 的指令们

获取指令

  • child-src 节点允许加载的url, 如: iframe frame等标签的加载限制
  • content-src 脚本允许请求的url, 如: xhr, ws
  • font-src 字体允许请求的url, 如: font-family
  • style-src css文件允许请求的url, 如: link标签
  • img-src 图片文件允许加载的url, 如: img
  • manifest-src manifest-src , 如: link标签中的manifest的文件
  • media-src 媒体文件, 如 audio,video
  • object-src object的加载文件, 如:
  • worker-src worker的来源指定
  • script-src 脚本文件允许加载url, 如: <script src>

以上的获取指令, 顾名思义, 即是通过限制资源的地址来源, 减少一个站点的加载外部资源的权限, 减缓xss的攻击,
除此之外, 还有一些个指令, 比如限制文件的类型, 运行的环境, 如下

在level 2.0 的基础上, script-src , style-src 等配置, 在原有host, 'http:', 'self', 'unsafe-inline', 'unsafe-eval', 值的基础上添加了 nonce-, -;
可选的值包括:

  1. host, 比如http://quanlincong.com, https://quanlincong.com
    2.scheme-source, 比如'http:','https:', 'data:', 'blob:', 等也是可以指定, 表示只加载这些个类型的资源
    3.'unsafe-inline', 表示可以执行内联方式的脚本, 比如
<a onclick="//todo something">干活了</a>
<script>
// todo something
</script>

可以执行这些
4.''unsafe-eval' , 可以执行 setTimeout, setInterval, new Function, eval 字符串代码
5.self, 表示当前域名下的都可以执行
6. 'nonce', 表示nonce后面的随机值, 需要再script 插入的时候同时指定script 标签的属性 nonce值, 这样script才会执行, 对于webpack 可以查看webpack csp nonce
7. '-', 表示内容的hash 值, 和nonce相同, 也是需要再meta 或者http header 里面预先定义, 在script下载的时候, 浏览器会自动检查内容hash和定义的hash是否包含在里面. 在CSP 2.0中,这仅适用于内联脚本, 在外链脚本的时候, csp 3.0可以用

文件指令

  • base-src base 标签, 作用是用来指定文档中加载的链接的前缀
  • plugin-typs embed, object ,标签加载插件类型
  • sandbox 加载运行danbox环境配置, 类似iframe 中的sanbox,包括 允许表单提交, 允许模态框弹出,允许新建window, 允许允许脚本等等.具体可看MDN,
    比如, 限制加载plugin的类型, 那么可以这样:
// plugin-types 限制加载特定的插件, applet, object, embed
<object data="https://example.com/flash" type="application/x-shockwave-flash"></object>

导航指令

  • form-action 限制可以用作来自给定上下文的表单提交的目标的URL
  • navigation-to 限制可以在页面中, 可允许window.open, a, location.href的调转路径
  • frame-ancestors 可以内嵌的iframe, frame, object, embed 的url, 这个指令和default-src, 差不多, 但是不允许 'unsafe-eval', 'unsafe-inline' 等值.

报告指令

- report-uri CSP1.0 版本支持的指令, 用于发送json报告给指定的uri, 这个指令已经过时了, 推荐使用report-to, 但report-to存在浏览兼容问题, 最好同时指定, 可以搭配 content-security-policy-only header 一起使用, 表示只发送安全报告到后台, 而不进行拦截

如果 content-security-policy-only 和 content-security-policy一起声明, 则2者都会生效,但是一般不会这么配置, 成本太高.

其他指令

  • block-all-mixed-content 中断https域名站点所有的http请求信息
  • referrer (过时) 这个将作用http 头部的 referrer , 其中 'no-referrer' 不发送referer 信息, 'none-when-downgrade' 是浏览器自动代理, 也是默认值, https->https 发送, https->http不发送refer
  • Referrer-Policy 和referrer一样, 是http的header的一个属性, 用来代替 csp 的referrer
  • require-sri-for 指定脚本, style等内容的加载必须验证完整性, 比如我们加载jquery的cdn ,一般都会有以下几个属性
<script src="https://code.jquery.com/jquery-3.1.1.slim.js"
        integrity="sha256-5i/mQ300M779N2OVDrl16lbohwXNUdzL/R2aVUXyXWA="
        crossorigin="anonymous"></script>

integrity: 就是script的内容 hash过后的序列, 浏览器加载完成之后会进行校验脚本, 和integrity是否一致. 可以防篡改. 所以一旦发送篡改, 浏览器会 block这个资源, 那么就需要我们额外的去判断是否发送篡改, 再重新去加载对应的js的资源信息.

crossorigin:: 这个属性有2个值,
一个是anonymous, 会在请求中的header中的带上Origin属性,但请求不会带上cookie和其他的一些认证信息,
二是use-credentials, 在跨域请求中带上cookie和其他的一些认证信息

sri, subresource intergrity 子资源完整性, 意义就是当前这个文档加载的内容, 是否篡改过的. 具体可以看这里 SRI in MDN
注意: 这个配置, 在firefox中, 从version 49 开始就是一个必须手动在about://config 中配置的参数, 必须打开才能开启, 而且chrome中也需要手动开启(虽然MDN上 写着chromes上从version54就开始完全兼容, 不需要开启, 但是我也没有找到相关配置开关, 配置也没生效??? ).
image

image

<meta http-equiv="Content-Security-Policy" content="require-sri-for script style;">
// 对 script style 启用完整性校验
  • upgrade-insecure-requests 针对https 下存在http资源请求的混合内容, 可以采用这个指令, ff , chrome下不会抛混合内容警告. 但是在firefox会另外有个警告, 关于升级http->https的请求(感觉作用不大)
    image

关于block-all-mixed-content几点问题?

在chrome, firefox中, 如果https的站点, 加载了http的资源, 这些资源包括, 混合被动内容(video, img, audio, object) , 混合活动内容(xhr, object, link, script,iframe), 那么会报一个警告, 如下图, 而ie下不兼容CSP, 兼容信息可以在文章结尾部分查看.
image
image
而且在websocket 部分, 也存在兼容的问题,

  • chrome 版本在50以上, https 的站点可以连接ws:// 协议开头的websocket
  • firefox 下, https的站点不能连接ws:// 协议开头的websocket, 必须要强制要求wss:// 协议开头, 且需要安装证书

csp 解决的问题

  1. 移动常会发送dns 协议, 或者http 挟持js, 往页面里面插播广告的情况, 用csp 加载js的限制可以有效控制, 此外 https:// 也是有效控制的一种手段.
  2. xss 攻击

关于浏览器兼容性

level 1.0的兼容性
image

非常遗憾,ie9及以下的浏览器连最基本的指令都不支持, ie10及以上, 支持x-content-security-policy的方式的开启方式

level 2.0的兼容性
image
添加base-uri,child-src,表单动作,框架 - 祖先,插件类型,引用链接器,反射-xss和报表 - uri。

参考

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
https://cloud.tencent.com/developer/chapter/13541

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant