安全相关HTTP响应头解读、配置、示例与检测
2020-02-14 10:31:51 Author: xz.aliyun.com(查看原文) 阅读量:253 收藏

设置HTTP响应头是在浏览器层面上提高Web安全性的一种方法,相比代码层的变动要更简单方便。由于HTTP协议是一个可扩展的协议,这些内容也在不断地变化,本文会试着做一个较为全面的总结。

关于众多浏览器的对响应头的支持、兼容性问题可以在CANIUSE网站搜索了解,示例:

https://caniuse.com/#feat=referrer-policy

部分响应头会有很细节的点无法展开总结,可以参考文末的Web文档进一步了解。

响应头解读与示例

HSTS

HTTP严格传输安全(HTTP Strict Transport Security)

本响应头,一言以蔽之,是为了防止非HTTPS连接带来的安全隐患。在设置Strict-Transport-Security响应头后,浏览器将会强制所有的HTTP请求使用HTTPS连接,且在证书错误或到期的情况下拒绝用户访问网站。

属性 描述
max-age 必选 作用时间,单位秒
includeSubDomains 可选 作用于所有子域名
preload 可选 是否纳入预加载列表

需要注意的是,最后的preload选项添加后,域名会被部分浏览器默认启用HSTS,从而阻止所有HTTP请求连接,因此需要谨慎使用。

响应头设置示例:

Strict-Transport-Security:max-age=31536000;includeSubDomains;preload

HPKP

由于受信任的CA可能遭受攻击(案例搜一搜有很多),HTTP公钥固定(Public Key Pinning Extension for HTTP)这种安全策略诞生,用于防止替换证书的中间人攻击(MITM)。

其中具体的技术实现包括证书的选择、OpenSSL生成指纹和首次使用信任(TOFU)等。但在这里我不想多总结,因为Chrome自69版本已经移除了对它的支持,有兴趣的同学可以参考RFC7469MDN Web文档。我们大概来了解一下它就好:

属性 描述
pin-sha256 必选 base64编码的证书的公钥指纹,可添加多个
max-age 必选 作用时间,单位秒
includeSubdomains 可选 HTTP公钥锁定是否覆盖子域
report-uri 可选 HPKP策略违规报告发送到的URL

示例:

Public-Key-Pins:
pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="; 
pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="; 
report-uri="http://0sec.com.cn/report"; 
max-age=10000;includeSubDomains

另外还有Public-Key-Pins-Report-Only头,如字面意思将只报告策略违规而不阻断连接。

Expect-CT

用于指示浏览器或客户端验证签名证书的时间戳,是上文的HPKP标头的替代品。

属性 描述
max-age=seconds 必选 作用时间,单位秒
enforce 可选 强制模式,拒绝违反策略的连接
report-uri 可选 CT策略违规报告发送到的的URL

示例:

Expect-CT:max-age=86400,enforce,report-uri="http://0sec.com.cn/report"

Referrer-Policy

显然是Referer头的安全配置策略,注意单词的拼写,请求头与响应头中的拼写是有差别的,绝了。

描述
no-referrer 不带referer头
no-referrer-when-downgrade 若协议降级如HTTPS到HTTP,则不会发送Referer头(默认策略)
same-origin 同源请求才发送Referer头
strict-origin 安全传输(如HTTPS到HTTPS)才发送Referer头
origin Referer头为origin
origin-when-cross-origin 同源发送完整URL,跨域发送origin
strict-origin-when-cross-origin 安全传输(如HTTPS到HTTPS)同源发送完整URL,跨域发送origin
unsafe-url 所有情况发送完整URL,

示例:

Referrer-Policy: no-referrer

Cache-Control

用于设置浏览器或代理的缓存机制,一部分指令也可以用在HTTP请求头中。

描述
max-age 有效时间,单位秒
public 所有内容都将缓存
private 仅在客户端缓存
no-cache 响应无变化时才使用缓存数据
no-store 所有内容均不缓存
must-revalidation 缓存失效则必须重新验证

示例:

Cache-Control:max-age=0,no-cache,no-store,must-revalidate

Expires

设置当前请求缓存的过期时间,需要注意的是Cache-Control的max-age响应头优先级高于Expires。

为安全起见可以拒绝浏览器缓存任何内容,设置如下:

Expires:0

具体时间格式示例:

Expires:Wed, 21 Oct 2015 07:28:00 GMT

X-Frame-Options

目的是为了减少点击劫持(Clickjacking),最终达成的效果就是站点的<frame>/<iframe>/<embed>/<object>内容是否被展示。

有三种配置参数:

  • DENY:不允许被任何页面嵌入
  • SAMEORIGIN:不允许被本域以外的页面嵌入
  • ALLOW-FROM uri:不允许被指定域名以外的页面嵌入

示例:

x-frame-options:SAMEORIGIN

CSP中的frame-ancestors选项与x-frame-options头有同样的作用。

X-XSS-Protection

用于启用浏览器的XSS过滤器。

描述
0 禁用XSS过滤器
1 启用XSS过滤器
1;mode=block 启用XSS过滤器且在检测到XSS时停止渲染页面
1;report=URL 启用且报告

示例(也是推荐的配置方法):

X-XSS-Protection:1,mode=block

当然了,这个XSS过滤器并不太强大,据我测试还是比较容易绕过的。

X-Content-Type-Options

用于阻止浏览器解析与Content-Type声明不一致的内容。

互联网上的资源有各种类型,通常浏览器会根据响应头的Content-Type字段来分辨它们的类型。例如:"text/html"代表html文档,"image/png"是PNG图片,"text/css"是CSS样式文档。然而,有些资源的Content-Type是错的或者未定义。这时,某些浏览器会启用MIME-sniffing来猜测该资源的类型,解析内容并执行。

例如,我们即使给一个html文档指定Content-Type为"text/plain",在IE8-中这个文档依然会被当做html来解析。利用浏览器的这个特性,攻击者甚至可以让原本应该解析为图片的请求被解析为JavaScript。通过下面这个响应头可以禁用浏览器的类型猜测行为:

以上解释来自Jerry Qu。这个响应头设置方法就是:

X-Content-Type-Options: nosniff

Content-Security-Policy(CSP)

算是应用比较多的响应头,其实就是白名单策略,在之前的文章中详细提过了,直接来看示例:

Content-Security-Policy:script-src 'self'; object-src 'none'; style-src 1.com 2.cn; child-src https

对应下方这张表来看,解释就是:

脚本只信任当前域名;标签不加载任何资源;样式表只信任http://1.comhttp://2.cn;框架(frame)必须使用HTTPS协议加载;其他资源没有限制。

指令 示例 说明
default-src 'self' cdn.example.com 定义资源默认加载策略
script-src 'self' js.example.com 定义 JS 的加载策略
img-src 'self' img.example.com 定义图片的加载策略
style-src 'self' css.example.com 定义样式表的加载策略
font-src font.example.com 定义字体的加载策略、
object-src 'self' 定义引用资源的加载策略,如<object> <embed><applet>
media-src media.example.com 定义音频和视频的加载策略,如 HTML5 中的<audio><video>
connect-src 'self' 定义 Ajax、WebSocket 等的加载策略
frame-src 'self' 定义 frame 的加载策略,不赞成使用,改用 child-src

X-Permitted-Cross-Domain-Policies

指定客户端能够访问的跨域策略文件的类型,比如我们熟悉的crossdomain.xml就是一个跨域策略文件。

描述
none 不允许使用策略文件
master-only 仅允许使用主策略文件
by-content-type 仅限HTTP(S)协议使用Content-Type:text-/x-cross-domain-policy提供的策略文件
by-ftp-filename 仅限FTP协议使用crossdomain.xml
all 可用目标域上所有策略文件

配置方法

以X-Frame-Options响应头为例,当然特定的语言、框架有对应的设置方法,这里举服务器配置的例子:

Apache

Header [always] set X-Frame-Options "sameorigin"

Nginx

add_header X-Frame-Options sameorigin [always];

IIS

<system.webServer>
  ...

  <httpProtocol>
    <customHeaders>
      <add name="X-Frame-Options" value="sameorigin" />
    </customHeaders>
  </httpProtocol>

  ...
</system.webServer>

lighthttpd

setenv.add-response-header = ("X-Frame-Options" => sameorigin",)

配置范例

新鲜复制的。

GitHub

Content-Security-Policy: default-src 'none'; base-uri 'self'; block-all-mixed-content; connect-src 'self' uploads.github.com www.githubstatus.com collector.githubapp.com api.github.com www.google-analytics.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com wss://live.github.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com; frame-ancestors 'none'; frame-src render.githubusercontent.com; img-src 'self' data: github.githubassets.com identicons.github.com collector.githubapp.com github-cloud.s3.amazonaws.com *.githubusercontent.com customer-stories-feed.github.com spotlights-feed.github.com; manifest-src 'self'; media-src 'none'; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com
Expect-CT: max-age=2592000, report-uri="https://api.github.com/_private/browser/errors"
Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: deny
X-XSS-Protection: 1; mode=block

Google

cache-control: private, max-age=0
expires: -1
strict-transport-security: max-age=31536000
x-frame-options: SAMEORIGIN
x-xss-protection: 0

Twitter

cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
content-security-policy: connect-src 'self' blob: https://(太多了); object-src 'none'; script-src 'self' 'unsafe-inline' https://*.twimg.com   https://www.google-analytics.com https://twitter.com  'nonce-MDRlMWY3ZTMtM2E5Yi00YjQxLTk5N2UtZTVmYzI5ZjA3ZTY2'; style-src 'self' 'unsafe-inline' https://*.twimg.com; worker-src 'self' blob:; report-uri https://twitter.com/i/csp_report?a=O5RXE%3D%3D%3D&ro=false
pragma: no-cache
strict-transport-security: max-age=631138519
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 0

设置检测工具

Analyse your HTTP response headers 在线分析

Check Your HTTP Security Headers 在线分析

Recx Security Analyser Chrome插件


参考


文章来源: http://xz.aliyun.com/t/7202
如有侵权请联系:admin#unsafe.sh