1.前言
记得刚来项目组时,每隔一段时间就报几个安全漏洞,然后就和团队小伙伴花一两天时间处理下,一会儿改java代码一会儿改前端,
前前后后也用去了很多时间。复盘整理下思路,发现走了不少弯路,大多数的安全漏洞都可以由nginx拦截,极少会涉及到后端业务代码调整。
安全问题属于系统架构级问题,要用系统架构的思维去解决 ,通过nginx配置,可以减少对后端业务开发的要求,而且现场实施人员,配置起来更可控
2. 常见安全问题
- 敏感信息泄露(中风险)
- 漏洞描述:功能接口存在错误信息,暴露出业务数据、中间件、数据库、服务器等相关信息。功能接口响应请求时返回了业务数据、中间件、数据库、服务器等相关信息,导致服务器信息泄露。
- 漏洞验证:通过请求 LINK 和 UNLINK 方法,服务端返回 501 状态码,返回数据中包括了Tomcat 服务器的版本信息:
- 修复建议:1、自定义错误页面。2、不要将服务器的有关信息返回至前端。3、敏感数据脱敏、加密。
- 不安全的HTTP方法(中风险)
- 漏洞描述:服务端开启了如 OPTIONS、TRACE 等不安全的 HTTP 方法,存在被非法利用、未授权访问的风险。
- 漏洞验证:服务端开启了 OPTIONS 方法:
- 修复建议:在不影响业务的情况下,服务端只开启 GET、POST 等方法。
- 跨域策略配置错误(中风险)
- 漏洞描述:跨域策略允许任意来源的请求,存在被非法跨域、跨站请求伪造的风险。
- 漏洞验证:Access-control-allow-origin:*
- 修复建议:在不影响业务的情况下,根据最小权限原则修改跨域配置。
-
隐藏nginx版本号
-
响应头漏洞
3.最终方案
常用的安全测量要求,只要修改nginx.conf配置即可
http{
#隐藏版本号
server_tokens off;
server {
listen 80;
server_name www.iwen.com;
# 响应头漏洞
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
# 利用Referer防盗链
valid_referers none blocked www.mydomain.com *.mydomain.com 10.24.30.40; # 这个地方不用写具体端口
if ($invalid_referer) {
return 403;
}
# 拦截不安全的HTTP方法,只允许GET、POST 方法
if ($request_method !~ ^(GET|POST)$) {
return 403;
}
# 防止Host渗透攻击 :检测到目标URL存在http host头攻击漏洞
set $flag 0; # 通过flag判断多个域名的方法
if ($http_Host = '10.85.24.28:8037') { # 若有端口写全端口
set $flag 1;
}
if ($http_Host = 'x.com') {
set $flag 1;
}
if ($flag != 1) {
return 403;
}
}
}
3.1. 如果是多个域名,采用下列方法
nginx不支持and、or表达式,需要通过set命令实现
# 判断多个域名的方法
set $flag 0;
if ($http_Host = '10.85.24.28:8037') # 这个若有端口写全端口
{
set $flag 1;
}
if ($http_Host = 'x.com')
{
set $flag 1;
}
if ($flag != 1) #
{
return 403;
}
3.2. 利用Referer防盗链
语法:valid_referers [none|blocked|server_names] …
默认值:no
使用字段:server, location
这个指令在referer头的基础上为 $invalid_referer 变量赋值,其值为0或1。
可以使用这个指令来实现防盗链功能,如果valid_referers列表中没有Referer头的值, $invalid_referer将被设置为1。
参数可以使如下形式:
none 意为不存在的Referer头(表示空的,也就是直接访问,比如直接在浏览器打开一个图片)
blocked 意为根据防火墙伪装Referer头,如:“Referer: XXXXXXX”。
server_names 为一个或多个服务器的列表,0.5.33版本以后可以在名称中使用“*”通配符。
例如:
location /photos/ {
valid_referers none blocked www.mydomain.com *.mydomain.com 10.24.30.40; # 这个地方不用写具体端口
if ($invalid_referer) {
return 403;
}
}
参考
- 检测到目标服务器启用了options方法(漏洞):通过java修改,后来不采用此方案
- tomcat版本号进行隐藏或者删除:通过修改tomcat方法改掉
- nginx 禁用不安全的http方法:通过前端拦截,可以禁用掉很多不合理应用方法
- 对于做医院、政府等高度要求安全的项目,建议api开发只使用GET、POST方法,以减少后面不必要的麻烦
- D12-Nginx-利用Referer防盗链: 如何设置,判断refer
- nginx if多条件判断