文章目录
本文解决的是跨域漏洞问题。
网上的多是如何实现跨域,这里是避免跨域。
场景
项目发现跨域漏洞。
也就是说,origin 设置为任意域名,都可以返回数据。这是不安全的。
实际应该只有指定的域名才可以返回数据。
目的: 不允许任意域访问数据。
解决方案
option的设置,实测无效
if ($request_method = 'POST') {
add_header Access-Control-Allow-Origin *; # 这里需要设置为自己的域名
add_header Access-Control-Max-Age 1728000;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header Content-Type' 'text/plain; charset=utf-8';
add_header Content-Length 0 ;
return 204;
}
deny和allow 可以么
配置:
satisfy all;
allow 127.0.0.1;
allow 192.168.0.1;
deny all;
修改origin为白名单,发现返回不了,只得作罢。
后来发现这个控制的是客户端ip,不是跨域origin地址,所以不管有效无效都是错的。
最终方案,判断$http_origin
原来: $http_origin是origin的值,如果不在白名单范围内,就返回403。
配置:
if ( $http_origin !~* 127.0.0.1|192.168.0.1|baidu|\*) { # 最后面的 \* 是为了匹配 * 号
return 403 ;
}
另一种写法(加小块号)也是可以的,如:
if ( $http_origin !~* (127.0.0.1|192.168.0.1|baidu|\*) )
注: 这里面可以使用正则表达式。
可以写ip,也可以写域名,或者域名的一部分。
实测有用。
可能的副作用:
1、如果后面跟着try_files,try_files可能会失效。
例如如果某个地址找不到,那么会重定向到index.html。加了如上代码之后,无法重定向了。现象是刷新或者页面直接输入地址,会报403。
还有可能同页面的下载也会有问题,报403。
目前先将就用着,其实应该找更好的方法。
其他
nginx默认是不允许跨域的
配置中没有找到开启跨域的内容,为什么会有跨域安全问题呢?
待解决。
使用geo改进丑陋的代码
if后面跟多条件,代码确实比较丑陋。可以用geo模块转换下,代码就清爽很多,而且可以复用。
geo中是可以使用掩码等方式的,但是不知道是否可以通配符匹配。
access配置为什么会重复
我们发现,返回的报文中,access属性可能会多个。
Access-Control-Allow-Origin: deny
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: aaa.com
这说明他不是覆盖的关系,而是并列存在的关系。
try_files 和 if不要同时使用
同时使用发现有问题。
可能会导致if无效,或者try_files无效。
建议if语句放在外面。