使用HTTP头加固你的网站
原文 有意思的是我使用mozilla的工具测试它们的主站 mozilla得分,也没得到满分。
Observatory by Mozilla 可以教育开发者、系统管理员、安全专家如何配置他们的网站,使之更加安全、牢固。本文介绍和安全有关的HTTP头。
1 Content Security Policy (CSP)
CSP控制站点可以从哪里引用脚本和资源,例如:
- default-src <source>, script-src <source>, object-src <source> 等配置资源的源。
https只能引用https的源https://example.com只能引用该站点的'self'只能引用本站的- 在 CSP:default-src 查看更多选项
Content Security Policy禁止<script>内联执行,可以通过标记'unsafe-inline'取消禁止,但是会使削弱站点的安全。可以通过指定nonce或SHA签名脚本内容以允许执行。frame-ancestors 'none'禁止站点在iframe中被引用,以避免 clickjacking 攻击 ,如果确实需要在iframe中被引用,可以指定url代替'none'。
我们的网站希望引用自身资源,twitter和aws的图片,google和twitter的脚本,google的css和字体等。我们还需要在一些指令中重新定义 'self' ,以覆盖默认值( default-src 'self' 指定了默认值)。最终配置如下:
Content-Security-Policy: default-src 'self';
script-src https://static.ads-twitter.com https://www.google-analytics.com;
img-src 'self' https://s3.amazonaws.com https://twitter.com https://pbs.twimg.com;
font-src 'self' https://fonts.gstatic.com;
style-src 'self' https://fonts.googleapis.com;
frame-ancestors 'none';
2 HTTP Strict Transport Security (HSTS)
HSTS 告诉浏览器,我们的站点仅接受HTTPS访问,HSTS提供下面的标记:
max-age=<seconds>这个指令告诉浏览器,未来这么久,对本站点的访问,必须通过HTTPS。这个标记使必须的。includeSubDomains包含子域preload如果配置了这个标记,并且在 Chrome HSTS preload list 注册了你的域名,在看到这个header前,就会强制使用https。(这个我没看懂)
最终设置是: Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
3 X-Content-Type-Options
这个头告诉浏览器,如果MIME类型和需要的不一致,不要加载script和stylesheets。例如:引用script资源,但是资源的MIME类型是text/plain,和需要的不一致,拒绝加载。
最终设置是: X-Content-Type-Options: nosniff
4 X-Frame-Options
提供的功能和CSP的 frame-ancestors 'none' 类似,但是浏览器的支持更广泛。
最终设置是: X-Frame-Options: DENY
5 X-XSS-Protection
用来避免XSS,和CSP中提供的功能类似,但是浏览器支持更广泛。
最终设置是: X-XSS-Protection: 1; mode=block
6 总结
添加上面的header后,firefox的console出现警告, 拒绝执行inline脚本,和如下的CSP策略冲突,"script-src https://static.ads-twitter.com https://www.google-analytics.com" 使用 'unsafe-inline' 或者 hash('sha256-q2sY7jlDS4SrxBg6oq/NBYk9XVSwDsterXWpH99SAn0=') 或者 nonce 可以解决 。即使我们把 https://www.google-analytics.com 添加到了 script-src ,因为使用了inline脚本,还需要显式开启允许inline执行。这里我们选择 'sha256-q2sY7jlDS4SrxBg6oq/NBYk9XVSwDsterXWpH99SAn0=' ,只有script的sha256是 q2sY7jlDS4SrxBg6oq/NBYk9XVSwDsterXWpH99SAn0= 才允许执行。最终配置的header是:
Content-Security-Policy: default-src 'self';
script-src https://static.ads-twitter.com https://www.google-analytics.com 'sha256-q2sY7jlDS4SrxBg6oq/NBYk9XVSwDsterXWpH99SAn0=';
img-src 'self' https://s3.amazonaws.com https://twitter.com https://pbs.twimg.com;
font-src 'self' https://fonts.gstatic.com;
style-src 'self' https://fonts.googleapis.com;
frame-ancestors 'none';
Referrer-Policy: no-referrer, strict-origin-when-cross-origin
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block