HTTP Security
HTTP CSP3
指标
- 缩小内容注入攻打的危险,包含:
1)嵌入文档的资源(worker/iframe)
2)内联脚本
3)动静脚本(eval)
4) 内联款式 - 提供能力管制嵌入资源能够应用哪些源(origin)
- 提供一个 report 机制
Directives
指令相干执行查看的机会:
- Pre-request check
- Post-request check
- Inline check
- Initialization
- Pre-navigation check
- Navigation response check
能够配置的 Source List
- 关键字 none 和 self(只匹配以后 URL 的 Origin)
- URL(例如: https://example.com/path/to/f…,特定的文件;https://example.com/,Origin 下所有的资源)
- 协定(例如: https:)
- 域名(例如:example.com,*.example.com)
- Nonces(例如:nonce-ch4hvvbHDpv7xCSvXCs3BrNggHdTzxUA,匹配页面上特定的元素例如: <script nonce=“ch4hvvbHDpv7xCSvXCs3BrNggHdTzxUA”…></script>)
- Digests(例如:sha256-abcd,匹配页面上特定的元素: 例如 <script integrity=“sha256-abcd”….><script>)
Policy Delivery
- 能够在 HTTP 返回头 Content-Security-Policy 申明
- 也能够在页面上的 meta 元素 http-equiv 属性上申明
Content-Security-Policy-Report-Only 响应头
能够容许开发者收集页面上违反 policy 的报告
然而这个响应头是不反对在 meta 标签上配置的
反对 meta 标签配置
例如:
<meta http-equiv="Content-Security-Policy" content="script-src'self'">
然而 Content-Security-Policy-Report-Only,report-uri, frame-ancestors,sandbox 也是不反对
如何捕捉和上报违规行为
当产生违规行为时,就会在 element 或者 windows 触发一个 SecurityPolicyViolationEvent 事件,
js 能够通过以下代码来进行捕捉
if ('SecurityPolicyViolationEvent' in window) { // Check browser support
window.addEventListener('securitypolicyviolation', function(e) {console.log( e.violatedDirective, e.originalPolicy);
});
}
所有指令
Fetch Directives
- child-src
能够管制 iframe,frame 和 worker 的申请加载 - connect-src
管制 fetch(),xhr, eventsource, beacon, a 标签,websocket 的申请加载 - default-src
能够作为其余 fetch directive 的默认值 - font-src
能够管制字体资源的申请加载 - frame-src
能够管制 ifream, frame 的申请加载 - Img-src
管制图片的申请加载 -
manifest-src
管制 manifest 的申请加载<link rel="manifest" href="https://example.org/manifest">
-
media-src
管制 video,audio 还有 track 等申请加载<audio src="https://example.org/audio"></audio> <video src="https://example.org/video"> <track kind="subtitles" src="https://example.org/subtitles"> </video>
- object-src
管制 embed,object 的申请加载 -
prefetch-src
<link rel="prefetch" src="https://example.org/"></link> <link rel="prerender" src="https://example.org/"></link>
-
script-src
不单止管制 script 元素的申请加载,还包含:- 内联 script block,除非 script-src 或者 default-src 没有设置为“unsafe-inline”或者 nonce-source,hash-source
- eval(),Function(), setTimeout 和 setInterval 第一个参数不是函数,除非 script-src 或者 default-src 设置为“unsafe-eval”
- 相似 javascript: 的 url 必须通过 script-src inline check
- script-src-elem
管制所有的 script 申请和 script block;然而相似 <div onclick=“alert(1)”></div> 内联事件处理器是 script-src-attr 解决管制的 - script-src-attr
管制相似元素上内联事件处理器 -
style-src
次要管制以下几点:- 所有的 style 申请,包含 style 元素,@import
- 内联 style block,除非 style-src 或者 default-src 没有设置为“unsafe-inline”或者 nonce-source,hash-source
- 批改 style 的 cssText 和其余 insertRule 办法,除非 script-src 或者 default-src 设置为“unsafe-eval”
- style-src-elem
管制 style 元素,然而不包含元素上的内联 style - style-src-attr
管制元素上的内联 style - worker-src
管制 Worker, ShareWorker 和 ServiceWorker 的申请加载
Document Directives
- base-url
管制 base 元素上的 url 设置 - sandbox
能够让页面上的 iframe 设置了 sandbox 属性一样
Navigation Directives
- form-action
管制表单的提交门路 -
frame-ancestors
能够管制资源是否在 frame,iframe, object, embed 等元素上加载展现
这个指令是跟 X -Frame-Options 响应头性能是类似的,frame-ancestors X-Frame-Options 意义
none DENY 禁止在 frame,iframe 等元素上加载展现
self SAMEORIGIN 只有是同源的时候才能够在 frame,iframe 上进行展现惟一不一样的是 X -Frame-Options 的 SAMEORIGIN,只会匹配最顶层页面的 URL;而 frame-ancestors 会查看所有的先人元素也就是 frame,iframe, object, embed;
而且 frame-ancestors 会笼罩 X -Frame-Options - navigate-to
管制整个页面的跳转,包含 a, form, window.loacation, window.open 等等形式的跳转
Reporting Directives
- report-to
能够设置上报的地址(然而感觉还是应用捕捉 SecurityPolicyViolationEvent 形式有更高的可控性)
CSP 规定的继承性
所有 iframe 加载时会复制一份 CSP 的规定,所以 iframe 也是不能绕过 CSP 的安全策略
HSTS(Strict-Transport-Security)
背景尽管目前大部分网站都反对 https,然而依然不代表相对的平安,其中之一场景就是浏览器与服务器之间建设链接时会先用发动 http 申请(如果没有应用 https 的 url),而后再重定向到 https 的 url,而发动 http 到重定向 https 过程中就会容易呈现中间人的攻打,所以这里就提供一种形式去躲避这个问题:
Strict-Transport-Security 响应头能够强制浏览器和服务器从一开始就建设 https 链接,而不是通过 http 申请再重定向 https,所以在第一次申请服务器胜利建设 https 链接并接管到 Strict-Transport-Security 响应头;那么浏览器在下一次申请服务器时就会间接发动 https 申请。
然而 HSTS 的形式还有一个破绽就是必须与服务器先建设起第一次 https 链接(两头就有可能从 http 再重定向到 https 的过程),这意味着攻击者还是有机会可乘,而谷歌这里保护着一个 HSTS preload service,只有在这下面胜利提交域名就会被硬编码到浏览器中,当浏览器对这些域名第一次发动申请时会间接走 https;然而这个是硬编码配置也就是象征只有等 chrome 更新版本才会失效,只能用作一个补充伎俩。
以前始终有一个错误想法,HSTS 会记录网站的证书而后建设链接时会进行比照(忘了网站的证书也是会更新的,所以没有意义)
一些跟平安相干的响应头
- X-Content-Type-Options
因为浏览器存在一种内容嗅探行为,只有在 Content-Type 没有设置或者 Content-Type 设置的类型跟理论内容不相符的时候就会呈现这种行为尝试去猜想理论的内容;
而 X -Content-Type-Options 会禁止这种嗅探行为,让浏览器依照 Content-Type 设置的类型去解释内容,而如果 script/style 申请返回的内容不是 JavaScript MIME type 或者 text/css 也会阻塞这些申请 - X-Frame-Options
能够管制页面上的 frame,iframe,embed 和 object 元素的加载,无效防止点击劫持等攻打
Cookie 平安相干属性
- Security
能够限度 cookie 只能在 https 链接下传输, 会话 token 应该设置为 security, 避免中间人攻打获取 token - HttpOnly
能够限度 cookie 不能通过 document.cookie 间接获取,避免 xss 攻打窃取 token -
SameSite
能够管制哪些 cookie 能够在跨站申请中传输(限度第三方 cookie),能够抵挡 csrf 攻打,目前 chrome 默认 SameSite=Lax什么是跨站申请?
首先要了解同域和同站区别,因为两者容易混同同域:两个 Origin 的 scheme+host+port 齐全相等
同站:一个站点残缺的名称是 eTLD+1,eTLD 就是无效 TLD,而 TLD(顶级域名) 也就是.com 和.org,eTLD 就是相似.co.jp 或者.github.io,这些域在公共后缀列表中进行定义;eTLD+ 1 就是 eTLD 加上后面一部分。
例如:
www.taobao.com 和 www.baidu.com 是跨站
www.a.taobao.com 和 www.b.taobao.com 是同站
a.github.io 和 b.github.io 是跨站(留神是跨站)所以在浏览器怎么判断一个申请是跨站申请
就是依据申请的指标站点和发动申请的站点是否同站,否则就是跨站申请了例如在 exampleA.com 页面应用 <form action=“exampleB.com”method=“post”></form> 提交给 exampleB.com 是不能够携带 exampleB.com 上设置了 SameSite 的 cookie
对于服务端咱们依然能够通过 HTTP 申请头 Sec-Fetch-Site 来判断申请起源(浏览器支持率并不是很高),Sec-Fetch-Site 有以下属性值 cross-site,same-site,same-origin,none
SameSite 不同属性值的区别:
如果 SameSite 属性值是“Strict”只能容许在同站申请上发送 cookie;
如果属性值是“Lax”,那么除了同站申请上依然能够发送 cookie,跨站的导航 (“cross-site” top-level navigations) 且申请办法是 GET 时也会发送 cookie
如果属性值是“None”,必须同时设置 Secure 属性才会失效,因为等于去掉 SameSite 的爱护,所以必须在 https 链接环境下确信没有中间人攻打那么什么是 top-level navigations,例如:从 exampleA.com 点击 a 标签跳转到 exampleB.com
所以意味着“Lax”条件下,依然可能存在破绽,在攻击者的网站能够:
- 应用链接跳转
- 应用 <link rel=’prerender’>
- 应用 <form method=”GET” action=”…”>
都会触发一次胜利的同站申请
SameSite 在 ShareWorker 和 ServiceWorker 环境下的成果:
首先确定 worker 以后的 site- ShareWorker 因为能够绑定多个 document,所以计算以后 ”site for cookies”算法是:
1)设置 worker_site 为 worker 注册的 domain
2) 遍历绑定 worker 的 document 列表,如果 document 列表上存在一个 document 的 site 与 worker_site 不匹配,则返回字符串为空
3)否则返回 worker_site - ServiceWorker 返回的是 worker 注册的 domain
而后依据计算的 site 来跟申请的 origin 比照确定是否是跨站或者同站申请,而后再利用 SameSite
ajax 申请中的 withCredentials 属性与 samesite
samesite 管制的跨站申请是否传输 cookie
withCredentials 管制的是跨域申请中是否传输 cookie
当一个申请既是跨域又是跨站申请,cookie 先会受到 samesite 属性影响,再受到 ajax 外面的 withCredentials 影响 -
SameParty
因为 SameSite 对于第三方 Cookie 限度太大,某些业务场景下难以实现(例如登陆淘宝 taobao.com 后应该能够跟天猫 tmall.com 共享登陆信息,所以就须要一个第三方 cookie 去共享)First-Party Sets policy
首先咱们一种策略把不同的站点标记成为同一方的站点,这样前面被标记为 SameParty 的 cookie 在这些站点之间传输才是荒诞不经
怎么定义 First-Party Sets?
例如有 brandx.site,fly-brandx.site,drive-brandx.site;brandx.site 作为最顶层的域名,必须在 /.well-known/first-party-set 门路下定义一下内容:{ "owner": "brandx.site", "version": 1, "members": ["fly-brandx.site", "drive-brandx.site"] }
而 fly-brandx.site,drive-brandx.site 也别离在 https://fly-brandx.site/.well…,https://drive-brandx.site/.we… 下定义
{"owner": "brandx.site"}
那么他们之间关系就能够明确定下来了
First-Party Sets policy 如何影响 cookie
如果在 brandx.site 设置以下 cookie:
Set-Cookie: session=123; Secure; SameSite=Lax; SameParty
那么当初从 fly-brandx.site 跳转到 brandx.site 就会主动带上这个 cookie(没有 SameParty 依然会受限制)然而留神:
- SameParty 设置必须与 Secure 一起
-
SameParty 不能与 SameSite=Strict 同时设置
CORS 与 CSRF
能够通过 Access-Control-Allow-Origin 设置,来限度跨域申请(很多时候为了图不便设置为“*”,其实很危险),对于抵挡 CSRF 也有很好的作用
参考资料
HTTP State Management Mechanism
SameSite
同站同源区别
CORS
SameParty
对于 cookie 的 samesite 和 xHr 的 withCredentials 的思考