CSRF

  • General
黑客获得用户有效的cookie,从黑客网站伪造用户请求,在用户认证服务器上非法操作。
  • 解决方案
1. Origin & Referer headers
Referer 从哪个页面链接过来的。
2. 改变状态的操作用POST,不能使用GET
3. CSRF Token
3.1 实现
session建立时生成CSRF Token,存储在session中,session结束后失效。可使用base64或者256-bit做哈希加密,使用java.security.SecureRandom类来生成token。
很多框架支持CSRF Token,java可使用OWASP CSRFGuard,有相应的library支持。
CSRF token使用java.security.SecureRandom类生成。

3.2 传统CSRF token设置的缺陷
GET在url中设置CSRF Token。PUT在表单中设置CSRF Token。黑客能直接从url中获得GET的CSRF Token,所以GET中不能使用CSRF Token。
Example for GET:
http://url?csrftoken=tokenvalue
Example for POST:
value="OWY4NmQwODE4ODRjN2Q2NTlhMmZlYWE...
wYzU1YWQwMTVhM2JmNGYxYjJiMGI4MjJjZDE1ZDZ...
MGYwMGEwOA==">
黑客也可以通过referer中获得csrf token。
3.3 优化设置
使用XMLHttpRequest,设置CSRF token到header中,不会在浏览器中留下数据。缺点是XMLHttpRequest适用于Ajax对局部页面的异步刷新。不在浏览器中留下数据,会影响前进后退。

4. Double submit cookie
提交请求前,将cookie取出来加入request的参数中(POST或者URL),服务器端验证两者是否一致。

5. Encrypted token pattern
服务器根据userId,timestamp和nonce,生成加密token。此token放在隐藏filed中发送给客户端。
客户端的ajax请求中把此token带在请求头中。
服务器端解密此token,获得的usrId和timestamp分别与当前用户和时间比较。

6. REST Services:使用Custom Request Headers
X-Requested-With:XMLHttpRequest
AJAX等会自动加入此header,对UI的影响不大。在XMLHttpRequest中加入安全验证信息。


  • CSRF攻击实例
银行网站A:通过GET请求完成转账,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000
危险网站B:
登录A网站后,再访问B,B使用A的有效token完成转账。

  • Background
浏览器同源策略 same-origin policy
如果不同源(协议,域名,端口),将受到限制:
无法访问cookie,local storage
无法读取response
无法读取dom
Ajax请求不能发送


由于nginx不支持.htaccess,所以,从这个方面直接去防止是行不通的,我们要通过修改配置文件来解决。
首先,我们找到需要防盗链的域名的conf文件,路径:/usr/local/nginx/conf/vhost/,比如guance.com.conf。先备份下原文件,然后找到下面的部分:
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)${expires 30d;}
将它修改为:
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)${valid_referers none blocked www.jb51.net jb51.net;if ($invalid_referer) {rewrite ^/ http://www.jb51.net/404.jpg;#return 404;}expires 30d;}
上面的内容,大家请根据个人的情况酌情修改,我这里做基本的解释:
第一行gif|jpg|jpeg|png……这些是您需要防止盗链的文件类型,您可以补充一些后缀类型;
第三行是你的网站的域名,就是说放行的域名,如果有多个,请添加,注意空格;
第五行是给盗链看到的图片,返回一个404.jpg,这个图片源地址是要可以外链的哦,不然,别人看到的也就一个XX。
完成之后保存,上传到原位置覆盖,之后重启下lnmp使之生效。
/root/lnmp restart
referer指令简介
nginx模块ngx_http_referer_module通常用于阻挡来源非法的域名请求.我们应该牢记,伪装Referer头部是非常简单的事情,所以这个模块只能用于阻止大部分非法请求.我们应该记住,有些合法的请求是不会带referer来源头部的,所以有时候不要拒绝来源头部(referer)为空的请求.
语法: referer_hash_bucket_size size;
默认值: referer_hash_bucket_size 64;
配置段: server, location
这个指令在nginx 1.0.5中开始出现.
Sets the bucket size for the valid referers hash tables. The details of setting up hash tables are provided in a separate document.
语法:     referer_hash_max_size size;
默认值:     referer_hash_max_size 2048;
配置段:     server, location
这个指令在nginx 1.0.5中开始出现.
Sets the maximum size of the valid referers hash tables. The details of setting up hash tables are provided in a separate document.
语法: valid_referers none | blocked | server_names | string ...;
默认值: —
配置段: server, location
指定合法的来源'referer', 他决定了内置变量$invalid_referer的值,如果referer头部包含在这个合法网址里面,这个变量被设置为0,否则设置为1.记住,不区分大小写的.
参数说明
none
“Referer” 来源头部为空的情况
blocked
“Referer”来源头部不为空,但是里面的值被代理或者防火墙删除了,这些值都不以http://或者https://开头.
server_names
“Referer”来源头部包含当前的server_names(当前域名)
arbitrary string
任意字符串,定义服务器名或者可选的URI前缀.主机名可以使用*开头或者结尾,在检测来源头部这个过程中,来源域名中的主机端口将会被忽略掉
regular expression
正则表达式,~表示排除https://或http://开头的字符串.


  • 参考
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
CSRF攻击实例的例子:
http://blog.csdn.net/u013934914/article/details/50428869


http://blog.csdn.net/stpeace/article/details/53512283


https://www.daguanren.cc/post/csrf-introduction.html CSRF的抵御(详细)


http://blog.csdn.net/Solmyr_biti/article/details/78151443?locationNum=4&fps=1

你可能感兴趣的:(CSRF)