nginx安全问题处理
# 背景
接到global安全团队反馈问题:
Security issues
- X-Content-Type-Options header is missing over https. You need to implement X-Content-Type-Options header, refer to Web Server configuration standard.
- X-Frame-Options header is missing over https. You need to implement X-Frame-Options header, refer to Web Server configuration standard.
- Content-Security-Policy header is missing over https. You need to implement Content-Security-Policy, refer to Web Server configuration standard.
- Incorrect value 'max-age=15724800; includeSubDomains' in Strict-Transport-Security header There might be a typo in the value that is currently setup, you need to check the configuration for that header and use the correct value 'max-age=31536000; includeSubDomains'.
此业务系统是部署在k8s集群内,通过ingress-nginx来暴露服务,所以需要在ingress规则中添加对应header来解决。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/server-snippet: >-
add_header X-Content-Type-Options nosniff;add_header X-Frame-Options ALLOWALL;add_header Strict-Transport-Security "max-age=31536000;includeSubdomains;";add_header Content-Security-Policy "script-src * 'unsafe-inline' 'unsafe-eval'";
name: ingress-e
spec:
rules:
- host: xxx.xxxxx.com
http:
paths:
- backend:
service:
name: jazz-ui-webui
port:
number: 80
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- xxx.xxxxx.com
secretName: xxxxx.com
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
对应header参数说明如下:
# X-Content-Type-Options
互联网上的资源有各种类型,通常浏览器会根据响应头的Content-Type字段来分辨它们的类型。例如: "text/html"代表html文档,"image/png"是PNG图片,"text/css"是CSS样式文档。然而,有些资源的Content-Type是错的或者未定义。这时,某些浏览器会启用MIME-sniffing来猜测该资源的类型,解析内容并执行。例如,我们即使给一个html文档指定Content-Type为"text/plain",在IE8-中这个文档依然会被当做html来解析。利用浏览器的这个特性,攻击者甚至可以让原本应该解析为图片的请求被解析为JavaScript。
禁用浏览器的类型猜测行为:nosniff
nosniff 只应用于以下两种情况的请求将被阻止:
- 请求类型是 style 但是 MIME 类型不是 text/css。
- 请求类型是 script 但是 MIME 类型不是 JavaScript MIME 类型。
add_header X-Content-Type-Options nosniff;
# X-Frame-Options
为了减少点击劫持(Clickjacking)而引入的一个响应头。这个响应头支持四种配置:
DENY:不允许被任何页面嵌入;
SAMEORIGIN:不允许被本域以外的页面嵌入;
ALLOW-FROM uri:不允许被指定的域名以外的页面嵌入(Chrome现阶段不支持);
ALLOWALL : 允许全部来源域名
add_header X-Frame-Options ALLOWALL;
# Content-Security-Policy
简称CSP,意为内容安全策略,通过 HTTP 响应标头传递,与HSTS非常相似,并定义了浏览器只加载的已批准内容源,通过设置约束指定可信的内容来源,降低异源文件攻击,有效防止跨站点脚本 (XSS) 攻击,例如:js/css/image等,它易于部署并且得到广泛支持。但是安全威胁较低,还需要熟悉每一个站点资源引用情况,如果后续资源引用发生变化还会导致错误。
CSP 常用指令名
指令名 demo 说明 default-src ‘self’ cdn.example.com 默认策略,可以应用于所有请求 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’ 定义页面的过滤策略,如 media-src media.example.com 定义媒体的过滤策略,如 frame-src ‘self’ 定义加载子frmae的策略 sandbox allow-forms allow-scripts 沙盒模式,会阻止页面弹窗/js执行等, report-uri /some-report-uri CSP 常用指令值
所有以-src结尾的指令都可以用以下的值来定义过滤规则,多个规则之间可以用空格来隔开
值 demo 说明 * img-src * 允许任意地址的url,不包括 blob: filesystem: schemes. ‘none’ object-src ‘none’ 所有地址的咨询都不允许加载 ‘self’ script-src ‘self’ 同源策略,即允许同域名同端口下,同协议下的请求 data: img-src ‘self’ data: 允许通过data来请求咨询 比如用Base64、SVG 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()方法
add_header Content-Security-Policy "script-src * 'unsafe-inline' 'unsafe-eval'";
# Strict-Transport-Security
Web 服务器对于 HTTP 请求的响应头中缺少 Strict-Transport-Security,这将导致浏览器提供的安全特性失效。 当 Web 服务器的 HTTP 头中包含 Strict-Transport-Security 头时,浏览器将持续使用 HTTPS 来访问 Web 站点,可以用来对抗协议降级攻击和 Cookie 劫持攻击。
- max-age=
: 设置在浏览器收到这个请求后的 xx 秒的时间内凡是访问这个域名下的请求都使用 HTTPS 请求。 - includeSubDomains :可选,如果这个可选的参数被指定,那么说明此规则也适用于该网站的所有子域名。
- preload: 可选,加入预加载列表
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains;";
参考:
https://securityheaders.com/
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy