Web 安全
CSRF
(Cross-site request forgery[伪造]):
全称为跨站请求伪造,一句话概述该攻击手法:盗用用户的身份认证信息在用户当前已登录的Web应用程序上执行非用户本意的操作
具体操作原理:
用户登录之后,服务器会将用户身份认证信息(用户Session)保存在用户浏览器的cookie中。如果当前用户没有登出,而恰巧又在Session过期之前受到诱惑后访问了一个潜伏着CSRF攻击的网站,该网站便会盗用用户当前浏览器的cookie来模拟用户想服务器发送请求,执行预谋的操作。
CSRF基于曹操
挟天子以令诸侯
的手段上做了创新
:挟天子以骗诸侯。
这样的盗用能够生效,有两个前提条件
1.用户没有登出当前网站,并且当前用户Session未过期。
2.用户受到的诱惑,真实打开了攻击网站
上面说这么多还是太模糊了,直接上场景:
场景还原
下班后,手机没电关机之前的最后一个电话是我一朋友打来借钱的。无奈我只能打开Chrome,访问了某银行网站,好在我成功登录(手机接到验证码后便关机了)
导航到转账页面,我输入好金额和对方账号,点击提交后,浏览器发起一个请求:
|
转账成功后,我开始浏览某论坛。某帖子有一个评论附了一张照片,我好奇地点击了照片,不料中招,链接地址是:
|
假如我恰好账户里有1000以上的存款.可能就会成功给黑客转账1000元…..god
你可能会纳闷,为什么这个转账操作会被服务器接受呢?
首先,黑客没有强制我去做什么,他也没法获取我从服务器上所获取的信息,他做的事情是向我访问的网站域名发出一个GET请求,而该请求会自动附上浏览器中该域(bank.cn)对应Cookie中的用户身份认证信息(Session未过期),所以服务器认为这是一个认证过的用户请求。更糟糕的是,服务器上没有留下黑客的任何非法攻击痕迹(当然收款方账号可能留下了技术之外的脚印),因为服务器认为该请求是我发起的。
上述只是为了叙述原理,简化了银行这边的校验。实际上,一般都会由reffer的ip地址校验,一般也不会用get请求来明文发支付相关的操作。
防御措施
|
所以如果我们从技术角度上防御CSRF攻击,主要有2个出发点
|
在展开讨论方案之前,我们先来剖析CSRF核心攻击点。用户对系统的使用,无非就是对服务器资源的CRUD(Create, Retrive, Update, Delete),由于R操作不会涉及到数据的更改,所以服务器要做的是防御客户端的CUD请求。而CSRF攻击正是黑客利用用户的Cookie信息伪造用户的CUD请求。所以我们要增加黑客无法盗用的东西,比如保存在Cookie之外的Token。
常用解决方案:增加额外校验机制,引入token
关于增加额外的校验机制,经典的做法是基于HTTP请求动作添加CSRF Token,即在请求参数或者Header中添加额外的Token
服务器首先会生成一个Token保存在Session中,然后返回客户端。客户端在提交CUD请求的时候附带Token,服务会从Session中取出Token与请求中的Token进行比对校验。
Spring security默认就启用了CSRF防御机制。如果我们发起的请求(POST, PUT, PATCH, DELETE)中没有携带任何CSRF的Token,服务器便会阻止请求:
如何附加token呢?
懒一点的话,直接在template渲染的时候,把token渲染到form里的隐藏域中。
最好的方式当然是通过Javascript脚本来添加token
另外的一种做法是HTTP header 中的 Referer
Referer字段主要记录了该HTTP请求的来源地址,那么在转账案件中,黑客模拟我发起转账的请求Header的Referer值就不是我所访问的银行网站的域名。服务器便可以拒绝该请求。
这种方案是否可靠取决于浏览器厂商的实现是否有安全漏洞,比如IE6的referer是可以被篡改的。
另外用户可能因为该机制会记录下访问来源而设置浏览器不再提供referer的值。这会导致正常用户请求也会被服务器拒绝。
作为开发者,应当遵守常规的HTTP规范,尤其当团队采用
XSS
(Cross-site scripting):
XSS攻击方式:
- 反射型
发出请求时,xss代码出现在url中,作为输入提交到服务器中,服务器解析后响应,xss代码随响应一起传回给浏览器,最后浏览器解析xss代码。这个过程就叫做一次反射。故称为反射型xss
具体实现方式例子:
get请求上url参数添加为’?param=‘
当url中参数加载解析图片时,因为图片的地址为null,则会触发onerror事件,这时候就会解析onerror里面的代码。alert(1)只是一种示范,
实际上很有可能就是一段攻击代码,被浏览器成功执行
防范措施:
1.编码处理
服务器部分接口可以过滤排除掉< 、> 、&等字符,或者进行转义。
2.过滤属性
联系一下我们是如何引用js的,一般也就是通过src、script。所以,当服务器模板渲染数据、或ajax回传的数据我们可以过滤掉iframe、script、src、style等标签和属性、同时过滤掉onClick等监听事件的dom属性。
如果是服务器渲染一次性推过来,那么就在服务器端渲染前,将模板数据进行dom parse、解码、过滤等操作。如果是ajax,就在前端做。
推荐库:HTML parse。
- 存储型
……