跨站脚本,通常缩写为XSS就是攻击者导致页面加载一些恶意的JavaScript攻击.X-XSS-Protection
在Chrome和Inter Explorer的中旨在防止反射型XSS攻击者发送包含恶意代码的请求攻击。
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"; |
PC版
浏览器名称 | Chrome | Firefox | Edge | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
是否支持 | YES | NO | YES | 8.0+ | YES | YES |
移动版
浏览器名称 | Android | Chrome | Firefox | Edge | IE mobile | Opera | Safari |
---|---|---|---|---|---|---|---|
是否支持 | YES | YES | NO | YES | ? | YES | YES |
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 " |
Apache | Header always set Content-Security-Policy " |
Varnish | set resp.http.Content-Security-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 |
更多参数点此查看
当我们想与某人进行安全通讯时,我们要面对两个问题:第一个问题就是隐私;我们想保证除了对方以外,没有第二个人能收到我们的信息。第二个问题就是身份认证;即我们怎么知道收到消息的人就是我们想发送的人。
HTTPS可以通过加密方式解决第一个问题,但是它在身份认证方面还是有一些问题。HSTS请求头可以解决"你自己知道与你通讯的人是否支持加密"这个问题。
HSTS可以减少sslstrip
攻击中间人攻击, 当你使用了一个被恶意攻击者控制的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
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=" |
Apache | Header always set Public-Key-Pins 'pin-sha256=" |
Varnish | set resp.http.Public-Key-Pins = "pin-sha256=" |
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
PC版
浏览器名称 | Chrome | Firefox | Edge | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
是否支持 | YES | 35.0 | NO | ? | YES | ? |
report-uri | 46 | NO | ? | ? | 33 | ? |
移动
浏览器名称 | Android | Chrome | Firefox | Edge | IE mobile | Opera | Safari |
---|---|---|---|---|---|---|---|
是否支持 | YES | YES | ? | 35.0 | ? | YES | ? |
report-uri | YES | YES | ? | NO | ? | 33 | ? |
用来给浏览器指示允许一个页面可否在 ,
,
中展现的标记。网站可以使用此功能,来确保自己网站的内容没有被嵌到别人的网站中去,也从而避免了点击劫持 (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/
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 |
移动端
浏览器名称 | Android | Chrome | Firefox | Edge | IE mobile | Opera | Safari |
---|---|---|---|---|---|---|---|
是否支持 | YES | YES | YES | YES | YES | YES | YES |
ALLOW-FROM | ? | ? | ? | ? | ? | ? | ? |
互联网上的资源有各种类型,通常浏览器会根据响应头的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"; |
在页面引入图片、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 信息
将Cookies标记成secure
将只会在HTTPS协议中传递,这样就可以防止攻击者中间人攻击时读取用户Cookies了。
HttpOnly
的cookie不能在javascript内访问。因此,如果存在XSS漏洞,攻击者就无法立即窃取cookie
SameSite
帮助防止跨源请求伪造(CSRF)攻击。这是一个用户可能访问的不同网站,无意中欺骗他们对你的站点提出请求,例如,通过包含一个图像来获取GET请求,或者使用javascript提交一个POST请求的表单。一般来说,人们使用CSRF令牌来抵御这种攻击。一个标记为SameSite的cookie不会被发送到另一个站点.它有两种模式:lax
和strict
。
lax
模式允许在GET请求上下文中发送cookie
,strict
模式则不发送任何第三方的cookie
平台 | 使用方法 |
---|---|
Rails4,5 | secure 和httponly 默认缺省时即开启,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: =<value>; Expires=<expiryDate>; Secure; HttpOnly; SameSite=strict
http请求这块还是挺基础的东西,一开始估计大家都没怎么仔细看,社区有个小伙伴买了本图解http协议,看了几天发现了一个可以无视国内waf的技巧。