安全 – CSP (Content Security Policy)
前言
之前讲过 CSRF。防 Cookie hacking 的。
也介绍过防 XSS 的 HtmlSanitizer。
今天再介绍 CSP。
参考
CSP (Content Security Policy) 介绍
它是游览器其中一种防 hack 机制。除 IE 以外,modern browser 老早就全部支持了,所以可以安心用。
它主要是防 html 里要加载的 resource。
比如 HTML 想加载 JavaScript, Image 等等。
首先游览器会去检查 CSP config,然后验证这些 resource 是否符合 config 要求,如果 ok 才加载,不 ok 就报错,不加载。
此外它还可以防 inline JavaScript 的执行,还有网页被 ifame 嵌套等等。算是满全面的防 hack 机制。
Config CSP
same origin resource
CSP 可以设置在 header,也可以放到 HTML 的 meta 里。
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
这是一个用 meta 定义 CSP 的例子。所有的 config 都会写到 content 里。分隔符是空格和分号。
用 header 的话,key 是 Content-Security-Policy,value 是 default-src 'self'。
CSP 可以配置不同 src 的条件,比如 script-src 指的是 JavaScript,img-src 指的是图片,而 default-src 指的是所有 src 默认的条件。
上面这句 default-src 'self' 意思是 HTML 里所有要加载的 resource 必须来自于 self / 同域 / same-origin。
<script src="/script.js"></script>
<script src="https://192.168.1.152:44300/script.js"></script>
假设我的 origin 是 http://localhost:5148,上面 /script.js 可以加载,但是 https://192.168.1.152:44300/script.js 就不行,因为它不是 same origin。
运行的结果就是游览器会报错。

wss: 和 https:
除了 https://192.168.1.152:44300/script.js,还有一个 resource 也被拒绝了 wss://localhost:61341,这个是 ASP.NET Core development mode 情况下开启的 websocket,作用是自动刷新 browser。
如果我们想 allow 它,可以这样配置。
<meta http-equiv="Content-Security-Policy" content="default-src 'self' wss:">
加了一个 wss:,我没有声明完整的 origin,只声明了 protocol,所有只要是 websocket 请求,不管什么 origin 都被允许。类似的设置还有 https: 表示只要是 https 安全请求就允许。
inline script
'self' 并不能 bypass inline script。
<script>alert('inline script');</script>
CSP 防御下,inline script 会报错。

unsafe-inline
<meta http-equiv="Content-Security-Policy" content="default-src 'self' wss: 'unsafe-inline'">
添加 unsafe-inline 就可以 bypass inline script 了,但是这个方法是相对不安全的操作,除非我们可以完全信赖 inline script。
更安全的 by pass 方式是通过 sha256。我们把 inline script 拿去 sha256 + base64 得到 hash。
然后这样配置 CSP
<meta http-equiv="Content-Security-Policy" content="default-src 'self' wss: 'sha256-HgfVE1WaRXdD1n+LcUazTiP/FMatVgqvpPh9iAxr2qE='">
只要 inline script 的内容 sha256 后和 CSP 匹配,那么游览器才允许执行代码。
要得到这个 sha256 有很多种方式
2. Chrome 报错的时候会提供 sha256 的 hash,参考上面的 error。
3. 通过 C#
var script = "alert('inline script');";
var sha256Script = SHA256.HashData(Encoding.UTF8.GetBytes(script));
var base64Hash = Convert.ToBase64String(sha256Script);
Console.WriteLine(base64Hash);
third party resource
<meta http-equiv="Content-Security-Policy" content="default-src 'self' wss: https://192.168.1.152:44300">
<meta http-equiv="Content-Security-Policy" content="default-src 'self' wss: https://192.168.1.152:44300/script.js"> <script src="https://192.168.1.152:44300/script.js"></script>
我们可以指定信任的 origin,比如 https://192.168.1.152:44300 表示所有这个 origin 的 resource 都可以加载运行。
如果只是单个 resource 就写完整 URL,https://192.168.1.152:44300/script.js
如果我们不是很信任这个 origin 的 script,我们还可以添加一个 sha256 验证。
<script src="https://192.168.1.152:44300/script.js" integrity="sha256-tZpBEqmrY4CizbfYTAoo3wFhDJOpv6HGhMzwex2TTMs=" crossorigin="anonymous" ></script>
只要 resource 的内容和 hash 不匹配,那就会报错。
best practice
最起码可以 set 一个 https:,确保所有通信是加密的
<meta http-equiv="Content-Security-Policy" content="default-src https:">
‘self’,只相信自己也是一个好习惯。
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
对你相信的 thrid party 开放
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://192.168.1.152:44300">
只开放一些 third party resource
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://192.168.1.152:44300/script.js">
用 sha256 确保 script 是预期中的
<meta http-equiv="Content-Security-Policy" content="default-src 'self' wss: 'sha256-HgfVE1WaRXdD1n+LcUazTiP/FMatVgqvpPh9iAxr2qE='"> <script src="https://192.168.1.152:44300/script.js" integrity="sha256-tZpBEqmrY4CizbfYTAoo3wFhDJOpv6HGhMzwex2TTMs=" crossorigin="anonymous" ></script>
<script>alert('inline script');</script>
nonce
参考:MDN – nonce
nonce 是一个比较弱的防 hack 机制。用上面完整的 CSP 会更理想。

我是看到 Facebook Page Embed generate 出来的 code 有放,所以这里才顺便提一下。
假设我们没有用 sha256,'self' 这些 CSP 来防 hack,并且我们被 XSS 了。hacker 插入了一个 inline script 到我们的页面。
nonce 的防 hack 方式是这样,首先后端需要 generate nonce 随机数。
这里给一个 ASP.NET Core Razor Pages 的例子
public void OnGet()
{
static string GenerateCryptoNonce()
{
var rng = RandomNumberGenerator.Create(); byte[] bytes = new byte[16];
rng.GetBytes(bytes); string nonce = Convert.ToBase64String(bytes); return nonce;
} Nonce = GenerateCryptoNonce(); Response.Headers.Append("Content-Security-Policy", $"default-src 'self' wss: 'nonce-{Nonce}'");
}
nonce 需要用 cryptographically 128 bit (16 bytes) 生成,然后转 base64。
然后把 nonce 放到 CSP config 里,还有每一个 script 中。
<script nonce="@Model.Nonce">
alert('ok')
</script>
游览器在执行 script 之前,会先看它是否有 nonce,并且需要和 response header 中的 CSP nonce 匹配。
如果有匹配就执行,没有就不报错。
hacker 通过 XSS 插入的 script 没办法知道 nonce 随机数,所以最终 hacker script 不会被游览器执行,网页也就安全了。
了解了它的原理,确实,它也没有很安全,所以大家还是按上面 best practice 做会更理想。
frame-ancestors and X-Frame-Options
frame-ancestors 是用来取代 X-Frame-Options 的,它们的作用是声明网页是否允许被其它网页 iframe 嵌入。通常是不允许的啦。
注意:它只可以通过 HTTP header 方式去声明,HTML meta 不可以哦。

我的 Index 想嵌套 About 进来 iframe。如果没有 CSP 这个操作是 ok 的。

现在我们去配置 CSP 阻止它。

在 about 的 response header 加上 CSP frame-ancestors 'none' 完全不允许任何网页嵌入。
效果


只允许同域嵌入

把 'none' 换成 'self' 就可以了。
允许指定的 origin 嵌入

放入指定的 origin 就可以了,可以放多个,分隔符是空格。
defualt-src + frame-ancestors 的写法是
default-src 'self'; frame-ancestors https://192.168.1.152:44300 https://192.168.1.152:4200
分隔符是分号。
总结
CSP 是游览器的一种安全机制。可以用来限制 HTML 加载的 resource (e.g. script, img)。
比如限制 resource 只能是同域,或者指定可信赖的 origin。甚至可以通过 sha256 确保加载的内容是预期的。
另外它还可以防 XSS inline script 还有防网页被其它网页 ifram 嵌入等等。
这个是 Apple 官网返回的 CSP

安全 – CSP (Content Security Policy)的更多相关文章
- CSP(Content Security Policy) 入门教程
参考: http://www.ruanyifeng.com/blog/2016/09/csp.html https://developer.mozilla.org/en-US/docs/Web/HTT ...
- Content Security Policy (CSP) 介绍
当我不经意间在 Twitter 页面 view source 后,发现了惊喜. <!DOCTYPE html> <html lang="en"> <h ...
- 网页安全政策"(Content Security Policy,缩写 CSP)
作者:阿里聚安全链接:https://www.zhihu.com/question/21979782/answer/122682029来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...
- Content Security Policy (CSP)内容安全策略
CSP简介 Content Security Policy(CSP),内容(网页)安全策略,为了缓解潜在的跨站脚本问题(XSS攻击),浏览器的扩展程序系统引入了内容安全策略(CSP)这个概念. CSP ...
- Content Security Policy (CSP)内容安全策略总结
跨域脚本攻击 XSS 是最常见.危害最大的网页安全漏洞. 为了防止它们,要采取很多编程措施,非常麻烦.很多人提出,能不能根本上解决问题,浏览器自动禁止外部注入恶意脚本?这就是"网页安全政策& ...
- Refused to execute inline event handler because it violates the following Content Security Policy directive: "xxx". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...')
/********************************************************************************* * Refused to exec ...
- Content Security Policy的学习理解
以下内容转载自 http://www.cnblogs.com/alisecurity/p/5924023.html 跨域脚本攻击 XSS 是最常见.危害最大的网页安全漏洞. 为了防止它们,要采取很多编 ...
- Content Security Policy减少劫持
Content Security Policy减少劫持 什么是CSP? CSP是由单词 Content Security Policy 的首单词组成,是HTML5带给我们的一套全新主动防御的体系,旨在 ...
- Content Security Policy 入门教程
阮一峰文章:Content Security Policy 入门教程
- Content Security Policy介绍
Content Security Policy https://content-security-policy.com/ The new Content-Security-Policy HTTP re ...
随机推荐
- Java的TimeStamp
Java的TimeStamp 很简单,我们可以这样声明 Timestamp ts=new Timestamp(new Date().getTime());这样我们就可以得到时间比较具体的一个类型转换! ...
- 持久化技术Mybatis知识精讲【形成知识体系篇】
环境要求 JDK1.8及以上版本 MySQL数据库 Apache Maven 3.6.1构建工具 IDEA/VSCode/Eclipse开发工具任选其一 思维导图:Xmind ZEN 技术要求 熟悉J ...
- [oeasy]python0112_扩展ascii_Extended_ascii_法文字符
法文字符 回忆上次内容 上次回顾了 字型编码的进化过程 从 7-seg 到 点阵字库 终于让字母.数字.标点 明确了字型 小写字符 占据了位置 法文字符 没有地方放了 添加图片注释,不 ...
- oeasy教您玩转vim - 005 - # 程序本质
程序本质 回忆上次内容 py 的程序是按照顺序 一行行挨排解释执行的 我们可以 python3 -m pdb hello.py 来对程序调试 调试的目的是去除 bug 别害怕 bug bug 会有 ...
- AT_tenka1_2015_qualB_b 题解
洛谷链接&Atcoder 链接 本篇题解为此题较简单做法及较少码量,并且码风优良,请放心阅读. 题目简述 给定一个集合形式,判断此集合是 dict 还是 set. 思路 简单的模拟题. 首先需 ...
- 学习笔记--Java中的数据类型
Java中的数据类型 /** * Java中的数据类型: * 程序当中有很多的数据,每一个数据拥有与之相关的类型. * * * 1. 数据类型的作用: * 不同类型的数据占用的空间大小不同,数据类型的 ...
- Ubuntu16.04升级openssh-9.8p1
7月1日OpenSSH官方发布安全更新,忙着处理的同时记录一下升级过程. 系统环境 root@NServer:~# cat /proc/version Linux version 3.4.113-su ...
- 【C】Re06 数组与指针
一.指针和数组 void pointerAndArray() { int array[5] = {1, 2, 3, 4, 5}; printf("pointer array -> %p ...
- 【Layui】08 时间线 Timeline
文档地址: https://www.layui.com/demo/timeline.html 常规时间线: <ul class="layui-timeline"> &l ...
- 使用 C# 和 ONNX 來玩转Phi-3 SLM
LLM 席卷世界刷新 AI 的认知之后,由于 LLM 需要的硬件要求实在太高,很难在普通设备上运行,因此 SLM 逐漸受到重視,Phi-3 SLM 是由 Microsoft 所开发的模型,可以在你的电 ...