1.连接安全性与加密

1.1 SSL/TLS

  • 传输层协议(Transport Layer Security/TLS)及其前身安全套接层(Secure Sockets Layer/SSL)为浏览器和服务器提供了端到端的加密手段,为互联网通信提供了安全可靠性保障。
  • 建议:对所有本地资源和引用资源都要妥善配置TLS。
  • 兼容性:所有主流浏览器均支持

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

  • HSTS 设置仅允许 HTTPS(SSL/TLS)方式连接服务器。
  • 避免潜在中间人攻击场景,比如 SSL Stripping
    可以避免很多潜在的中间人攻击场景,
  • 相关配置存在错误的站点。
    为HTTPS站点设置HSTS相关的返回头可以激活浏览器的HSTS功能。

点这里手动添加网址加入主流浏览器内置的默认HSTS列表中

  • 隐患:HSTS的 includeSubDomains 会覆盖所以子域名,可能导致覆盖过广无法访问的情况。如果证书过期,此时浏览器会完全拒绝网页连接。

添加配置

  • 语法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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:可选,谷歌维护的https的列表,主流的浏览器都使用该列表。

    1.HSTS 设置max-age字段设置过期时间。 建议半年以上
    2.在nginx配置中,http -> server -> location

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains;preload" always;

1.3 HTTP公钥固定(HTTP Public—Key Pinning/HPKP)

  • HTTP公钥固定要求浏览器只在服务器提供已信任的某几张SSL/TLS证书(或者由已信任的中间证书/根证书签发起的子证书)时发起链接。如果SSL/TLS证书发生预期之外的变化时,浏览器会拒绝访问。避免多数证书欺诈行为。
  • 像HSTS一样,部署HPKP需要三思,错误的部署会导致用户无法访问你的站点,并且难以修复。

生成

1
2
3
4
5
6
7
8
9
# 检查证书是否符合 x509 规范,顺便通过 CN 字段确认证书在证书链上的位置
openssl x509 -in chain.pem -noout -subject
# 确认该证书为 Let's Encrypt Authority X3 中间证书
subject= /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
# 生成公钥
$ openssl x509 -in chain.pem -noout -pubkey | openssl asn1parse -noout -inform pem -out public.key
# 生成指纹
$ openssl dgst -sha256 -binary public.key | openssl enc -base64
YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg=

配置

http->server->location

add_header Public-Key-Pins 'pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; pin-sha256="/DPi+1wSZeogvO1OfgffRC6vM2LfvjaCfUV5Q2tqqtY="; max-age=2592000; includeSubDomains';

也可以直接放到http下 那样的就是包含根域名以及所有子域名

重启nginx

2.内容安全性

2.1 网页安全策略(Content Security Policy/CSP)

  • CSP是一个白名单,告诉浏览器资源哪些外部资源可以加载和执行。
  • CSP通过指定有效域——即浏览器认可的可执行脚本的有效来源——使服务器管理者有能力减少或消除XSS攻击所依赖的载体。
  • 老项目资源比较零散,难以整理白名单。可以使用CSP 的report-only模式,该模式不执行限制,只记录违规操作并上报服务器。
  • 防止XSS攻击。

语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Content-Security-Policy  配置好并启用后,不符合 CSP 的外部资源就会被阻止加载。

Content-Security-Policy-Report-Only 表示不执行限制选项,只是记录违反限制的行为。它必须与report-uri选项配合使用。

// 限制所有的外部资源,都只能从当前域名加载
Content-Security-Policy: default-src 'self'

// default-src 是 CSP 指令,多个指令之间用英文分号分割;多个指令值用英文空格分割
Content-Security-Policy: default-src https://host1.com https://host2.com; frame-src 'none'; object-src 'none'

// 错误写法,第二个指令将会被忽略
Content-Security-Policy: script-src https://host1.com; script-src https://host2.com

// 正确写法如下
Content-Security-Policy: script-src https://host1.com https://host2.com

// 通过report-uri指令指示浏览器发送JSON格式的拦截报告到某个地址

Content-Security-Policy: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;

// 报告看起来会像下面这样
{
"csp-report": {
"document-uri": "http://example.org/page.html",
"referrer": "http://evil.example.com/",
"blocked-uri": "http://evil.example.com/evil.js",
"violated-directive": "script-src 'self' https://apis.google.com",
"original-policy": "script-src 'self' https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"
}
}

配置

1
2
3
修改 Nginx 配置,http->server->location中添加,也可以直接在http下添加这样就是指定所有的

add_header Content-Security-Policy "default-src 'self' *.google-analytics.com *.swiftypecdn.com *.swiftype.com *.gstatic.com *.disqus.com *.disquscdn.com *.google.com *.facebook.com *.pippio.com *.crwdcntrl.net *.bluekai.com *.exelator.com *.narrative.io disqus.com 'unsafe-inline'; img-src * data: blob:";

配置内容详情

2.2 Frame Options

  • Frame Options控制页面是否允许被以下标签引入。禁止引入可以防止点击劫持(Clickjacking)式攻击。

    1
    <iframe>、<frame>、<object>
  • X-Frame-Options是一个标准响应头。在CSP 2.0标准中已经被Frame Options取代。然而CSP 2.0 还没普及,所以X-Frame-Options还在广泛使用。

配置

  • 如果站点没有frame渲染,使用deny可以完全禁止引入。
  • 或者使用sameorigin只允许同域引入。
  • 避免使用allow-from字段,兼容性差。
    1
    2
    修改Nginx配置 http->server->location
    add_header X-Frame-Options deny;

参数

  • DENY

    1
    表示该页面不允许在frame中展示,即便是在相同域名的页面下嵌套也不允许。
  • SAMEORIGIN

    1
    表示该页面可以在相同的域名页面下frame中展示。
  • ALLOW-FROM uri

    1
    表示该页面可以在指定来源的frame中展示。(兼容性很差)

2.3 XSS保护(XSS Protection)

  • 大部分浏览器默认开启XSS or CSS保护功能。
  • 也可以自己在Nginx配置增强功能。

配置

1
2
修改Nginx配置,http->server->location
add_header X-XSS-Protection "1; mode=block"

语法

1
2
3
4
5
6
7
8
9
10
X-XSS-Protection: 0
X-XSS-Protection: 1
X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; report=<reporting-uri>

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

2.4 缓存控制(Cache Control)

  • 指定页面的缓存策略。错误的换粗会导致性能问题和安全问题。
  • Cache-Control通用消息字段被用于在http请求和响应中通过指令实现缓存机制。
  • 缓存指令是单向的,这意味着在请求设置的指令,在响应的指令不一定包含相同的指令。

配置

1
2
3
修改Nginx配置,http->server->location

add_header Cache-Control 'no-cache';

语法

  • 缓存请求指令

    1
    2
    3
    4
    5
    6
    7
    Cache-Control: max-age=<seconds>
    Cache-Control: max-stale[=<seconds>]
    Cache-Control: min-fresh=<seconds>
    Cache-control: no-cache
    Cache-control: no-store
    Cache-control: no-transform
    Cache-control: only-if-cached
  • 缓存响应指令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Cache-control: must-revalidate
    Cache-control: no-cache
    Cache-control: no-store
    Cache-control: no-transform
    Cache-control: public
    Cache-control: private
    Cache-control: proxy-revalidate
    Cache-Control: max-age=<seconds>
    Cache-control: s-maxage=<seconds>
  • 扩展指令

    1
    2
    3
    Cache-control: immutable
    Cache-control: stale-while-revalidate=<seconds>
    Cache-control: stale-if-error=<seconds>
  • 可缓存性

    • public 表明响应可以被任何对象(包括:发送请求的客户端,代理服务器等等)缓存。
    • private 表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存),可以缓存响应内容。
    • no-cache 在释放缓存副本之前,强制高速缓存将请求提交给原始服务器进行验证。
    • only-if-cached 表明客户端只接受已缓存的响应,并且不要向原始服务器是否有更新的拷贝。
    • 到期 max-age= 设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires相反,时间是相对于请求的时间。
    • s-maxage= 覆盖max-age或者Expires头,但是仅适用于共享缓存(比如各个代理),并且缓存私有存储中它被忽略。
    • max-stale [=] 表明客户端愿意接收一个已经过期的资源。可选的设置一个时间(单位秒),表示响应不能超过的过时时间。
    • min-fresh= 表示客户端希望在指定的时间内获取最新的响应。
    • stable-while-revalidate= 表明客户端愿意接收陈旧的响应,同时在后台异步检查新的响应。秒值指示客户愿意接收陈旧响应的时间长度。
    • stale-if-error= 表示如果新的检查失败,则客户愿意接受陈旧的响应。秒数值表示客户在初始到期后愿意接收陈旧响应的时间。
    • must-revalidate 缓存必须在使用之前验证旧资源的状态,并且不可使用过期资源。
    • proxy-revalidate 与must-revalidate 作用相同,但它仅适用于共享缓存(例如代理),并被私有缓存忽略。
    • immutable 表示响应正文不会随时间而改变。资源(如果未过期)在服务器上不会发生改变,因此客户端不应该发送重新验证请求头(例如if-None-Match或if-Modified-Since)来检查更新,即使用户显式刷新页面。在Firefox中,immutable只能被用在https://transactions有关更新信息。
    • no-store 缓存不应存储有关客户端请求或服务器响应的任何内容,
    • no-transform 不得对资源进行转换或转变。Content-Encoding,Content-Range,Content-Type等HTTP头不能由代理修改。非透明代理可以对图像格式进行转换,以便节省缓存空间或者减少缓慢链路上的流量。no-transform指令不允许这样做。

2.5 Content Type Options

  • 通常浏览器根据响应头的Content Type字段分辨资源类型,但假若某些资源Content Type是错的或未定义的,浏览器会启用MIME-sniffing来猜测该资源的类型,解析内容并执行。

  • 假设你的站点有图片上传功能,用户上传一个html文档,这是即使服务器声明该资源Content Type为图片,浏览器依然会按照html进行渲染
    通过非标准的X-Content-Type-Options响应头可以关闭浏览器的资源MIME-sniffing功能。

配置

1
2
3
修改Nginx配置,http->server->location

add_header X-Content-Type-Options nosniff;

语法

  • X-Content-Type-Options响应首部相当于一个提示标志,被服务器用来提示客户端一定要遵循Content-Type首部中队MIME类型的设定,而不能对其修改。

  • 这就禁止了客户端的MIME类型嗅探行为,换句话说,也就是意味着网站管理员确定自己的设置没有问题。

  • X-Content-Type-Options:nosniff

    • 假如请求类型为以下两种,那么阻止请求的发生:”style” 但是 MIME 类型不是 “text/css”,”script” 但是 MIME 类型不是 JavaScript MIME 类型。

2.6 子资源完整性(Subresource Integrity/SRI)

  • 浏览器一般都会从域内载入资源(CDN)。既然资源托管在第三方服务器,就有被篡改的风险。
  • SRI通过对资源进行摘要签名的方式,保证外联资源不被篡改。

示例

1
2
3
<link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/frameworks-81a59bf26d881d29286674f6deefe779c444382fff322085b50ba455460ccae5.css" integrity="sha256-gaWb8m2IHSkoZnT23u/necREOC//MiCFtQukVUYMyuU=" media="all" rel="stylesheet">

假如资源完整性检查失败,资源就不会载入,往往导致页面无法正常工作。一定要做好降级措施。

配置

1
- 将使用base64编码过后的文件哈希值写入你引入的<script>或<link>标签的integrity属性值中即可启用子资源完整性功能。
  • integrity值分成两部分,第一部分指定哈希值的生成算法(目前支持sha256、sha384、sha512),第二部分是经过base64编码的实际哈希值,用-分割。

生成SRI哈希工具

1
2
3
4
5
6
openssl
cat FILENAME.js | openssl dgst -sha384 -binary | openssl enc -base64 -A

shasum

shasum -b -a 384 FILENAME.js | xxd -r -p | base64

内容安全策略及子资源完整性

  • 配置内容安全策略来使文件遵守SRI,通过CSP添加。
    1
    2
    // 这条指令规定了所有JavaScript都要有integrity属性,且通过验证才能被加载。
    Content-Security-Policy: require-sri-for script;
  • 也可以指定所有样式表也要通过SRI验证。
    1
    Content-Security-Policy: require-sri-for style;

2.7 Iframe Sandbox

  • 网页中的iframe运行的脚本很可能影响到整个页面。为iframe指定sandbox属性中内容行为进行限制。

配置

  • 为页面中的iframe添加合适的sandbox属性,只给必要的权限。
    1
    <iframe sandbox='allow-same-origin allow-scripts'></iframe>

2.8 服务器时钟

3.信息泄露

3.1 Server Banner

  • 大多数服务器都会在响应头加入Server Banner来标明自己的身份和版本号,比如:
    server:nginx/1.10.0(Ubuntu)。
  • 没有什么实际用处但是最好需要把版本号删掉,这样可能在某个版本暴漏bug后,可以降低他人攻击的可能性。

配置

1
2
3
修改Nginx配置 http下

server_tokens off;

3.2 Web框架信息

4.Cookie

4.1 Cookie安全

配置

1
2
3
// 建议把所有cookie都加上secure和httponly字段

Set-Cookie:Key=value;path=/;secure;HttpOnly,Key2=Value2;secure;Httponly

如有侵权行为,请点击这里联系我删除

如发现疑问或者错误点击反馈

原文链接,略有修改

备注