HTTP Security

HTTP CSP3

指标

  1. 缩小内容注入攻打的危险,包含:
    1) 嵌入文档的资源(worker/iframe)
    2)内联脚本
    3)动静脚本(eval)
    4) 内联款式
  2. 提供能力管制嵌入资源能够应用哪些源(origin)
  3. 提供一个report机制

Directives

指令相干执行查看的机会:

  1. Pre-request check
  2. Post-request check
  3. Inline check
  4. Initialization
  5. Pre-navigation check
  6. Navigation response check

能够配置的Source List

  1. 关键字none和self(只匹配以后URL的Origin)
  2. URL(例如: https://example.com/path/to/f...,特定的文件;https://example.com/,Origin下所有的资源)
  3. 协定(例如: https:)
  4. 域名(例如:example.com,*.example.com)
  5. Nonces (例如:nonce-ch4hvvbHDpv7xCSvXCs3BrNggHdTzxUA,匹配页面上特定的元素例如: <script nonce=“ch4hvvbHDpv7xCSvXCs3BrNggHdTzxUA” …></script>)
  6. Digests (例如:sha256-abcd,匹配页面上特定的元素: 例如<script integrity=“sha256-abcd”….><script>)

Policy Delivery

  1. 能够在HTTP返回头Content-Security-Policy申明
  2. 也能够在页面上的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
  1. child-src
    能够管制iframe,frame和worker的申请加载
  2. connect-src
    管制fetch(),xhr, eventsource, beacon, a标签, websocket的申请加载
  3. default-src
    能够作为其余fetch directive的默认值
  4. font-src
    能够管制字体资源的申请加载
  5. frame-src
    能够管制ifream, frame的申请加载
  6. Img-src
    管制图片的申请加载
  7. manifest-src
    管制manifest的申请加载

        <link rel="manifest" href="https://example.org/manifest">
  8. 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>
  9. object-src
    管制embed,object的申请加载
  10. prefetch-src

    <link rel="prefetch" src="https://example.org/"></link><link rel="prerender" src="https://example.org/"></link>
  11. 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
  12. script-src-elem
    管制所有的script申请和script block;然而相似<div onclick=“alert(1)”></div> 内联事件处理器是script-src-attr解决管制的
  13. script-src-attr
    管制相似元素上内联事件处理器
  14. 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”
  15. style-src-elem
    管制style元素,然而不包含元素上的内联style
  16. style-src-attr
    管制元素上的内联style
  17.  worker-src
    管制Worker, ShareWorker和ServiceWorker的申请加载
Document Directives
  1. base-url
    管制base元素上的url设置
  2. sandbox
    能够让页面上的iframe设置了sandbox属性一样
Navigation Directives
  1. form-action
    管制表单的提交门路
  2. 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

  3. navigate-to
    管制整个页面的跳转,包含a, form, window.loacation, window.open等等形式的跳转
Reporting Directives
  1. 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平安相干属性

  1. Security
    能够限度cookie只能在https链接下传输, 会话token应该设置为security, 避免中间人攻打获取token
  2. HttpOnly
    能够限度cookie不能通过document.cookie间接获取,避免xss攻打窃取token
  3. 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”条件下,依然可能存在破绽,在攻击者的网站能够:

    1. 应用链接跳转
    2. 应用<link rel='prerender'>
    3. 应用<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影响
  4. 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的思考