HTTP安全请求头

HTTP安全请求头
发布于 13 天前 作者 zhutougg 270 次浏览 来自 知识碎片

X-XSS-Protection

功能

跨站脚本,通常缩写为XSS就是攻击者导致页面加载一些恶意的JavaScript攻击.X-XSS-Protection

在Chrome和Inter Explorer的中旨在防止反射型XSS<sub>攻击者发送包含恶意代码的请求</sub>攻击。

X-XSS-Protection: 0; (关闭XSS过滤)
X-XSS-Protection: 1; (启用XSS过滤,如果检测到跨站脚本攻击,浏览器将清除页面(删除不安全的部分))
X-XSS-Protection: 1; mode=block  (启用XSS过滤。 如果检测到攻击,浏览器将不会清除页面,而是阻止页面加载)
1; report=<reporting-URI>  (Chromium only) (启用XSS过滤。 如果检测到跨站脚本攻击,浏览器将清除页面并使用CSP report-uri指令的功能发送违规报告)

使用方法
平台 使用方法
Rails4,5 使用默认即可
Django 使用SECURE_BROWSER_XSS_FILTER = True
Express.js 使用helmet
go 使用unrolled/secure
Nginx add_header X-XSS-Protection "1; mode=block";
Apache Header always set X-XSS-Protection "1; mode=block"
Varnish set resp.http.X-XSS-Protection = "1; mode=block";
浏览器兼容性
  1. PC版

    浏览器名称 Chrome Firefox Edge Internet Explorer Opera Safari
    是否支持 YES NO YES 8.0+ YES YES
  2. 移动版

    浏览器名称 Android Chrome Firefox Edge IE mobile Opera Safari
    是否支持 YES YES NO YES ? YES YES

Content Security Policy

功能

Content Security Policy可以看成X-XSS-Protection的更高级版本。虽然X-XSS-Protection能阻止来自请求中的XSS攻击,但是它并不能阻止来自本服务器上恶意的脚本或者链接到外面服务器上的恶意脚本。

CSP定义了浏览器可以加载的资源来源。你可以为script,images,fonts,css设置一个白名单

使用方法

CSP不能阻止所有的XSS攻击,但是它能明显减轻XSS的攻击影响,在深度防御XSS中是一个重要的方式

平台 使用方法
Rails4,5 使用secureheaders
Django 使用django-csp
Express.js 使用helmet/csp
go 使用unrolled/secure
Nginx add_header Content-Security-Policy "<policy>";
Apache Header always set Content-Security-Policy "<policy>"
Varnish set resp.http.Content-Security-Policy = "<policy>";
使用示例

Content-Security-Policy: script-src 'self' https://apis.google.com

只会下载本域及apis.google.com中的脚本

Content-Security-Policy "base-uri 'self'

限制文档base元素中只能使用当前域名

浏览器兼容性
浏览器名称 Chrome Firefox Edge IE mobile Opera Safari
是否支持 25+ 23.0+ 14+ 10+ 15+ 7+
meta元素 YES 45+ YES NO YES YES

更多参数点此查看

HTTP Strict Transport Security (HSTS)

功能

当我们想与某人进行安全通讯时,我们要面对两个问题:第一个问题就是隐私;我们想保证除了对方以外,没有第二个人能收到我们的信息。第二个问题就是身份认证;即我们怎么知道收到消息的人就是我们想发送的人。

HTTPS可以通过加密方式解决第一个问题,但是它在身份认证方面还是有一些问题。HSTS请求头可以解决"你自己知道与你通讯的人是否支持加密"这个问题。

HSTS可以减少sslstrip攻击<sub>中间人攻击</sub>, 当你使用了一个被恶意攻击者控制的WIFI网络,攻击者可以使你与服务器之间的加密无效。即使网站仅支持HTTPS协议,攻击者也可以通过HTTP流量进行中间人攻击,不需要SSL证书。

Strict-Transport-Security请求头可以告诉浏览器必须始终使用你网站的加密。只要你使用了HSTS请求头并且没有过期,它就会不允许网站不加密,当请求不是通过HTTPS的时候就会爆错。

使用方法
平台 使用方法
Rails4 config.force_ssl = true,默认情况下不要包含子域名,config.ssl_options = { hsts: { subdomains: true } }
Rails5 config.force_ssl = true
Django SECURE_HSTS_SECONDS = 31536000 SECURE_HSTS_INCLUDE_SUBDOMAINS = True
Express.js 使用helmet
go 使用unrolled/secure
Nginx add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; ";
Apache Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains;
Varnish set resp.http.Strict-Transport-Security = "max-age=31536000; includeSubdomains; ";
使用示例
Strict-Transport-Security: max-age=<expire-time>
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains
Strict-Transport-Security: max-age=<expire-time>; preload

HTTP Public Key Pinning(HPKP)

功能

WEB上的信息是建立在证书颁发机构(CA)模型上的。两个CA可以向两个不同的人发送同一个域的证书,并且浏览器都信任他们,这就产生了一个问题,这种情况下,CA证书是可以“被妥协”的,所以攻击者就可以中间人攻击他们想攻击的目标,尽管那些目标站使用了SSL和HSTS!

HPKP请求头就是来解决这个问题的,这个请求头可以绑定一个证书。当浏览器第一次收到这个请求头的时候,它就会保存该证书。对于在max-age时间范围内的所有请求,浏览器都会返回失败,除非从服务器发送的信息中至少有一个证书是被绑定了的。

使用方法
平台 使用方法
Rails4,5 Use secureheaders
Django Write custom middleware
Express.js 使用helmet
go 使用unrolled/secure
Nginx add_header Public-Key-Pins 'pin-sha256="<primary>"; pin-sha256="<backup>"; max-age=5184000; includeSubDomains';
Apache Header always set Public-Key-Pins 'pin-sha256="<primary>"; pin-sha256="<backup>"; max-age=5184000; includeSubDomains';
Varnish set resp.http.Public-Key-Pins = "pin-sha256="<primary>"; pin-sha256="<backup>"; max-age=5184000; includeSubDomains";
使用示例
Public-Key-Pins: pin-sha256=<base64==>; max-age=<expireTime>;
Public-Key-Pins: pin-sha256=<base64==>; max-age=<expireTime>; includeSubDomains
Public-Key-Pins: pin-sha256=<base64==>; max-age=<expireTime>; report-uri=<reportURI>

includeSubDomains :HPKP适用的子域名

report-uri:发送报告URL

浏览器兼容性
  1. PC版

    浏览器名称 Chrome Firefox Edge Internet Explorer Opera Safari
    是否支持 YES 35.0 NO ? YES ?
    report-uri 46 NO ? ? 33 ?
  2. 移动

    浏览器名称 Android Chrome Firefox Edge IE mobile Opera Safari
    是否支持 YES YES ? 35.0 ? YES ?
    report-uri YES YES ? NO ? 33 ?

X-Frame-Options

功能

用来给浏览器指示允许一个页面可否在 <frame>,<iframe>,<object>中展现的标记。网站可以使用此功能,来确保自己网站的内容没有被嵌到别人的网站中去,也从而避免了点击劫持 (clickjacking) 的攻击

使用方法
平台 使用方法
Rails4,5 sameorigin设置成默认,并且设置DENY为config.action_dispatch.default_headers['X-Frame-Options'] = "DENY"
Django MIDDLEWARE = [ ... 'django.middleware.clickjacking.XFrameOptionsMiddleware', ... ],sameorigin设置成默认, 设置DENY为X_FRAME_OPTIONS = 'DENY'
Express.js 使用helmet
go 使用unrolled/secure
Nginx add_header X-Frame-Options "deny";
Apache Header always set X-Frame-Options "deny"
Varnish set resp.http.X-Frame-Options = "deny";
示例
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
X-Frame-Options: ALLOW-FROM https://example.com/

浏览器兼容
  1. PC端

    浏览器名称 Chrome Firefox Edge Internet Explorer Opera Safari
    是否支持 4.0 3.6.9 YES 8.0 10.50 4.0
    ALLOW-FROM NO 18 ? 8.0 ? YES
  2. 移动端

    浏览器名称 Android Chrome Firefox Edge IE mobile Opera Safari
    是否支持 YES YES YES YES YES YES YES
    ALLOW-FROM ? ? ? ? ? ? ?

X-Content-Type-Options

功能

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

使用方法
平台 使用方法
Rails4,5 使用默认配置即可
Django SECURE_CONTENT_TYPE_NOSNIFF = True
Express.js 使用helmet
go 使用unrolled/secure
Nginx add_header X-Content-Type-Options nosniff;
Apache Header always set X-Content-Type-Options nosniff
Varnish set resp.http.X-Content-Type-Options = "nosniff";

Referrer-Policy

功能

在页面引入图片、JS 等资源,或者从一个页面跳到另一个页面,都会产生新的 HTTP 请求,浏览器一般都会给这些请求头加上表示来源的Referrer 字段,但是Referrer的值中可能包含用户的敏感信息,如session-id等。

Referrer-Policy请求头允许你自定义浏览器发送的referrer字段内容。

使用方法
平台 使用方法
Rails4,5 使用secureheaders
Django 编写自定义中间的
Express.js 使用helmet
go 编写自定义中间的
Nginx add_header Referrer-Policy "no-referrer";
Apache Header always set Referrer-Policy "no-referrer"
Varnish set resp.http.Referrer-Policy = "no-referrer";
示例
Referrer-Policy: "no-referrer" //任何情况下都不发送 Referrer 信息

Referrer-Policy: "no-referrer-when-downgrade" //仅当发生协议降级(如 HTTPS 页面引入 HTTP 资源,从 HTTPS 页面跳到 HTTP 等)时不发送 Referrer 信息.浏览器默认采用

Referrer-Policy: "origin" //发送只包含 host 部分的 Referrer

Referrer-Policy: "origin-when-cross-origin" //仅在发生跨域访问时发送只包含 host 的 Referrer,同域下还是完整的

Referrer-Policy: "same-origin"   //跨域时不发送referrer

Referrer-Policy: "strict-origin"   //HTTPS->HTTPS发送  HTTPS->HTTP不发送 

Referrer-Policy: "strict-origin-when-cross-origin" //跨域时HTTPS->HTTPS发送  HTTPS->HTTP不发送

Referrer-Policy: "unsafe-url"  //统统都发送 Referrer 信息

Cookie Options

功能

将Cookies标记成secure将只会在HTTPS协议中传递,这样就可以防止攻击者中间人攻击时读取用户Cookies了。

HttpOnly的cookie不能在javascript内访问。因此,如果存在XSS漏洞,攻击者就无法立即窃取cookie

SameSite帮助防止跨源请求伪造(CSRF)攻击。这是一个用户可能访问的不同网站,无意中欺骗他们对你的站点提出请求,例如,通过包含一个图像来获取GET请求,或者使用javascript提交一个POST请求的表单。一般来说,人们使用CSRF令牌来抵御这种攻击。一个标记为SameSite的cookie不会被发送到另一个站点.它有两种模式:laxstrict

lax模式允许在GET请求上下文中发送cookie,strict模式则不发送任何第三方的cookie

使用方法
平台 使用方法
Rails4,5 securehttponly默认缺省时即开启,samesite使用secureheaders
Django cookies默认被设置为httponly,设置secure:SESSION_COOKIE_SECURE = True
Express.js cookie: { secure: true, httpOnly: true, sameSite: true }
go http.Cookie{Name: "foo", Value: "bar", HttpOnly: true, Secure: true}
Nginx 不在Nginx中设置
Apache 不在Apache中设置

示例:

Set-Cookie: <key>=<value>; Expires=<expiryDate>; Secure; HttpOnly; SameSite=strict

http请求这块还是挺基础的东西,一开始估计大家都没怎么仔细看,社区有个小伙伴买了本图解http协议,看了几天发现了一个可以无视国内waf的技巧。😆😆

@iswin 就看了几天吗???书名叫啥?

@iswin THX,我看了这个图解http的PDF,日本人的安全书籍,不禁让我想起之前阅读过的一本书《Web应用安全权威指南》 对了,这里有一个国外版本的http安全请求头的介绍(有带demo演示):https://www.nwebsec.com/HttpHeaders/SecurityHeaders


为您推荐了相关的技术文章:

  1. Pwn2Own2017专题:VMWARE UAF漏洞分析
  2. 蓝牙App漏洞系列分析之一CVE-2017-0601
  3. HTTP安全请求头
  4. 从新浪微博一处Flash XSS到XSS Worm | 离别歌
  5. TCP 协议简介

原文链接: threathunter.org