使用以下HTTP头部可帮你快速容易地预防XSS攻击、点击挟持攻击、MIME嗅探和中间人攻击。如果目前还没使用,通过介绍给你,你可以在你的应用或服务器上使用。
1.Content-Security-Policy
引入https://www.cnblogs.com/zhangzhijian/p/10579974.html
什么是Content-Security-Policy?
翻译:内容安全策略,从名称可以看出该头部是用来限定网页内容安全的,缩写 SCP。说白了,就是为了页面内容安全而制定的一系列防护策略. 通过CSP所约束的的规责指定可信的内容来源(这里的内容可以指脚本、图片、iframe、fton、style等等可能的远程的资源)。通过CSP协定,让WEB处于一个安全的运行环境中。
有什么用?
我们知道前端有个很著名的”同源策略”,简而言之,就是说一个页面的资源只能从与之同源的服务器获取,而不允许跨域获取.这样可以避免页面被注入恶意代码,影响安全.但是这个策略是个双刃剑,挡住恶意代码的同时也限制了前端的灵活性,那有没有一种方法既可以让我们可以跨域获取资源,又能防止恶意代码呢?
答案是当然有了,这就是csp,通过csp我们可以制定一系列的策略,从而只允许我们页面向我们允许的域名发起跨域请求,而不符合我们策略的恶意攻击则被挡在门外.从而实现
需要说明的一点是,目前主流的浏览器都已支持csp.所以我们可以放心大胆的用了.
指令说明
指令就是csp中用来定义策略的基本单位,我们可以使用单个或者多个指令来组合作用,功能防护我们的网站.
以下是常用的指令说明:
指令名 | demo | 说明 |
---|---|---|
default-src | 'self' cdn.example.com | 默认策略,可以应用于js文件/图片/css/ajax请求等所有访问。 |
script-src | 'self' js.example.com | 定义js文件的过滤策略 |
style-src | 'self' css.example.com | 定义css文件的过滤策略 |
img-src | 'self' img.example.com | 定义图片文件的过滤策略 |
connect-src | 'self' | 定义请求连接文件的过滤策略 |
font-src | font.example.com | 定义字体文件的过滤策略 |
object-src | 'self' | 定义页面插件的过滤策略,如 <object>, <embed> 或者<applet>等元素 |
media-src | media.example.com | 定义媒体的过滤策略,如 HTML6的 <audio>, <video>等元素 |
frame-src | 'self' | 定义加载子frmae的策略 |
sandbox | allow-forms allow-scripts | 沙盒模式 |
report-uri | /some-report-uri |
沙河模式:,会阻止页面弹窗/js执行等,你可以通过添加allow-forms allow-same-origin allow-scripts allow-popups, allow-modals, allow-orientation-lock, allow-pointer-lock, allow-presentation, allow-popups-to-escape-sandbox, and allow-top-navigation 策略来放开相应的操作。
指令值
所有以-src结尾的指令都可以用一下的值来定义过滤规则,多个规则之间可以用空格来隔开
值 | demo | 说明 |
---|---|---|
* | img-src * | 允许任意地址的url,但是不包括 blob: filesystem: schemes |
'none' | object-src 'none' | 所有地址的咨询都不允许加载 |
'self' | script-src 'self' | 同源策略,即允许同域名同端口下,同协议下的请求 |
data: | img-src 'self' data: | 允许通过data来请求咨询 (比如用Base64 编码过的图片). |
domain.example.com | img-src domain.example.com | 允许特性的域名请求资源 |
*.example.com | img-src *.example.com | 允许从 example.com下的任意子域名加载资源 |
https://cdn.com | img-src https://cdn.com | 仅仅允许通过https协议来从指定域名下加载资源 |
https: | img-src https: | 只允许通过https协议加载资源 |
'unsafe-inline' | script-src 'unsafe-inline' | 允许行内代码执行 |
'unsafe-eval' | script-src 'unsafe-eval' | 允许不安全的动态代码执行,比如 JavaScript的 eval()方法 |
浏览器支持(基本上最新版的的浏览器都是支持的。)
具体怎么用
前面说到了他其实就是一个http header嘛,所以我们只需要在返回html页面的同时加上个response header 就行了,后面的script-src代表是一个指令,指示浏览器你只能加载我屁股后面那些规则下的js代码,其他的都一律拒绝。
两种方式:
方式一:在html页面的head标签内增加元标记的方式。
<meta http-equiv="Content-Security-Policy" content="default-src https://example.com; child-src 'none'; object-src 'none'">
方式二:response header的方式。
在返回的response 头部添加策略配置
Content-Security-Policy: script-src 'self' https://example.com
nonce属性
如果你在使用CSP策略的同时有确实需要使用内联css和js怎么办?用nonce+随机数的方式。作用就是开放一部分权限。
<script nonce=EDNnf03nceIOfn39fn3e9h3sdfa>
//Some inline code I cant remove yet, but need to asap.
</script>
然后我们在CSP的白名单中加上。
Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
这样你这段内联js就可以生效了。
2. X-Frame-Options
什么是X-Frame-Options?
翻译:图框选项。我们都知道html中有一个iFrame 标签很强大可以引入自己或者第三方的页面图片到自己的网页。反过来别人也可能引入我们的页面。这样容易被劫持,怎么处理呢,除了在请求头做域名过滤还可以禁止别人引入我们的页面。这里就用到了X-Frame-Options。
怎么用?
X-Frame-Options 有三个值:
DENY
表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。
SAMEORIGIN
表示该页面可以在相同域名页面的 frame 中展示。
ALLOW-FROM uri
表示该页面可以在指定来源的 frame 中展示。
例子
Note: 设置 meta 标签是无效的!例如 <meta http-equiv="X-Frame-Options" content="deny">
没有任何效果。不要这样用!只有当像下面示例那样设置 HTTP 头 X-Frame-Options
才会生效。
配置 Apache
配置 Apache 在所有页面上发送 X-Frame-Options 响应头,需要把下面这行添加到 'site' 的配置中:
Header always set X-Frame-Options "sameorigin"
要将 Apache 的配置 X-Frame-Options
设置成 deny , 按如下配置去设置你的站点:
Header set X-Frame-Options "deny"
要将 Apache 的配置 X-Frame-Options
设置成 allow-from
,在配置里添加:
Header set X-Frame-Options "allow-from https://example.com/"
配置 nginx
配置 nginx 发送 X-Frame-Options 响应头,把下面这行添加到 'http', 'server' 或者 'location' 的配置中:
add_header X-Frame-Options sameorigin always;
配置 IIS
配置 IIS 发送 X-Frame-Options
响应头,添加下面的配置到 Web.config 文件中:
<system.webServer>
...
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="sameorigin" />
</customHeaders>
</httpProtocol>
...
</system.webServer>
配置 HAProxy
配置 HAProxy 发送 X-Frame-Options
头,添加这些到你的前端、监听 listen,或者后端的配置里面:
rspadd X-Frame-Options:\ sameorigin
或者,在更加新的版本中:
http-response set-header X-Frame-Options sameorigin
配置 Express
要配置 Express 可以发送 X-Frame-Options
header,你可以用借助了 frameguard 来设置头部的 helmet。在你的服务器配置里面添加:
const helmet = require('helmet');
const app = express();
app.use(helmet.frameguard({ action: "sameorigin" }));
或者,你也可以直接用 frameguard:
const frameguard = require('frameguard')
app.use(frameguard({ action: 'sameorigin' }))
总之就是在http头部添加X-Frame-Options信息。在springMVC中推荐使用拦截器。在springBoot中推荐使用EnableWebSecurity注解:
例子:
import com.alibaba.spring.websecurity.DefaultWebSecurityConfigurer;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.header.writers.frameoptions.WhiteListedAllowFromStrategy;
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
import java.util.Arrays;
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends DefaultWebSecurityConfigurer {
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
//disable 默认策略。 这一句不能省。
http.headers().frameOptions().disable();
//新增新的策略。
http.headers().addHeaderWriter(new XFrameOptionsHeaderWriter(
new WhiteListedAllowFromStrategy(
Arrays.asList("http://itaobops.aliexpress.com", "https://cpp.alibaba-inc.com",
"https://pre-cpp.alibaba-inc.com"))));
}
}
上面是支持ALLOW-FROM uri的设置方式。
其他设置方式比较简单。 下面是支持SAMEORIGIN的设置方式:
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends DefaultWebSecurityConfigurer {
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.headers().frameOptions().sameOrigin();
}
}
下面是支持完全放开的方式:
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends DefaultWebSecurityConfigurer {
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.headers().frameOptions().disable();
}
}
结果
在 Firefox 尝试加载 frame 的内容时,如果 X-Frame-Options 响应头设置为禁止访问了,那么 Firefox 会用 about:blank 展现到 frame 中。也许从某种方面来讲的话,展示为错误消息会更好一点。
3.X-Content-Type-Options
什么是X-Content-Type-Options?
翻译:内容-类型-选项,HTTP 消息头相当于一个提示标志,被服务器用来提示客户端一定要遵循在 Content-Type
首部中对 MIME 类型 的设定,而不能对其进行修改。这就禁用了客户端的 MIME 类型嗅探行为,换句话说,也就是意味着网站管理员确定自己的设置没有问题。
该消息头最初是由微软在 IE 8 浏览器中引入的,提供给网站管理员用作禁用内容嗅探的手段,内容嗅探技术可能会把不可执行的 MIME 类型转变为可执行的 MIME 类型。在此之后,其他浏览器也相继引入了这个消息头,尽管它们的 MIME 嗅探算法没有那么有侵略性。
安全测试人员通常期望站点设置了该消息头。
语法
X-Content-Type-Options: nosniff
指令
nosniff
下面两种情况的请求将被阻止:
请求类型是"style
" 但是 MIME 类型不是 "text/css",
请求类型是"script
" 但是 MIME 类型不是 JavaScript MIME 类型.
怎么用?
当服务器响应头X-Content-Type-Options: nosniff则script和styleSheet元素会过滤非指定的MIME文件
stylesheet
stylesheet标签只会加载以下MIME类型的文件
text/css
script
script标签只会加载以下MIME类型的文件
application/ecmascript
application/javascript
application/x-javascript
text/ecmascript
text/javascript
text/jscript
text/x-javascript
text/vbs
text/vbscript
4. Strict-Transport-Security
什么是Strict-Transport-Security?
翻译:严格的运输安全,我们从 名字上可以联系到什么,是HTTPS安全传输协议。作用只有一个是一个安全功能,它告诉浏览器只能通过HTTPS访问当前资源,而不是HTTP。
语法
Strict-Transport-Security: max-age=<expire-time>
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains
Strict-Transport-Security: max-age=<expire-time>; preload
指令
max-age=<expire-time>
设置在浏览器收到这个请求后的<expire-time>秒的时间内凡是访问这个域名下的请求都使用HTTPS请求。
includeSubDomains | 可选
如果这个可选的参数被指定,那么说明此规则也适用于该网站的所有子域名。
preload | 可选
查看 预加载 HSTS 获得详情。不是标准的一部分。
注意: Strict-Transport-Security 在通过 HTTP 访问时会被浏览器忽略; 因为攻击者可以通过中间人攻击的方式在连接中修改、注入或删除它. 只有在你的网站通过HTTPS访问并且没有证书错误时, 浏览器才认为你的网站支持HTTPS 然后使用 Strict-Transport-Security 的值
浏览器如何处理
你的网站第一次通过HTTPS请求,服务器响应Strict-Transport-Security 头,浏览器记录下这些信息,然后后面尝试访问这个网站的请求都会自动把HTTP替换为HTTPS。
当HSTS头设置的过期时间到了,后面通过HTTP的访问恢复到正常模式,不会再自动跳转到HTTPS。
每次浏览器接收到Strict-Transport-Security头,它都会更新这个网站的过期时间,所以网站可以刷新这些信息,防止过期发生。
Chrome、Firefox等浏览器里,当您尝试访问该域名下的内容时,会产生一个307 Internal Redirect(内部跳转),自动跳转到HTTPS请求。
示例场景
你连接到一个免费WiFi接入点,然后开始浏览网站,访问你的网上银行,查看你的支出,并且支付一些订单。很不幸,你接入的WiFi实际上是黑客的笔记本热点,他们拦截了你最初的HTTP请求,然后跳转到一个你银行网站一模一样的钓鱼网站。 现在,你的隐私数据暴露给黑客了。
Strict Transport Security解决了这个问题;只要你通过HTTPS请求访问银行网站,并且银行网站配置好Strict Transport Security,你的浏览器知道自动使用HTTPS请求,这可以阻止黑客的中间人攻击的把戏。
示例
现在和未来的所有子域名会自动使用 HTTPS 连接长达一年。同时阻止了只能通过 HTTP 访问的内容。
Strict-Transport-Security: max-age=31536000; includeSubDomains
网友评论