CSRF(Cross Site Request Forgery,跨站请求伪造)
概述
csrf是一种迫使用户在已授权登录的网站执行非用户自身希望的操作的攻击。在社工帮助下(例如通过邮件或聊天发送链接),攻击者能七篇网站的用户去执行攻击者所要的操作。如果受害者是一个普通用户,成功的CSRF攻击能执行状态修改请求,例如转移资金或改变邮件地址等。如果受害者是管理员,CSRF能够危害整个web应用。
介绍
CSRF是一种欺骗用户发送而已请求的攻击。它继承受害者的身份和权限代替受害者执行并非本身希望的操作。对大部分网站,浏览器请求自动包含任何去网站相关的凭据,比如用户会话cookie,IP地址等。因此,如果用户最近登录一个网站,这个网站将无法分辨伪造的请求和真正的请求。
CSRF攻击能够修改状态的请求,比如修改受害者的邮件和密码或着购买东西。迫使受害者访问数据并不会对攻击者有好处,因为攻击者无法接收到响应,而受害者可以。因此,CSRF攻击是以状态改变的请求包为目标。
有时候能够将CSRF攻击保存在网站中。这类漏洞叫做"stored CSRF flaws"。这能够通过在目标网站中简单地存储IMG或者IFRAME的标签完成(比如写完文章后的自定义标签),或者通过更复杂的XSS攻击。如果攻击者能够在网站中存储CSRF攻击,那么这个攻击的严重程度将会被放大。
synonyms
CSRF攻击也以很多其他名字为人们所知。包括XSRF,“Sea Surf”,Session Riding,Cross-Site Reference Forgery,和Hostile Linking。微软在他们的危险建模过程以及许多他们的在线文档中,将这类攻击称为One-Click attack
无用的预防措施
使用私密cookie
请记住,所有的cookie,甚至私密的cookie,都要随每个请求被提交。无论用户是否被欺骗而提交请求,所有的认证令牌都会随之被提交。此外,会话标识(session identifiers)仅被web应用用来练习请求和特定的会话对象。因此会话标识并不能验证用户是否打算提交这个请求。
只接收POST请求
web应用能够开发成只接收POST请求以执行业务逻辑。误解是这样的,因为攻击者无法构建恶意链接,所以CSRF攻击无法被执行。不幸的是,这个逻辑是不正确的。攻击者有大量方法欺骗受害者发送伪造的POST请求,例如托管在攻击者网站上带有隐藏值的表单。这个表单能够被JS自动提交,或被受害者以为做其他事而触发提交。
随着时间推移,已经出现了许多为了抵御CSRF攻击的有缺陷的想法。这里有几个我们建议你避免使用的方法。
多步执行(Multi-Step Transactions)
多步执行不足以阻止CSRF。只要攻击者能够预测或推断完整执行的每个步骤,那么CSRF是可能的。
覆写URL
这个可能是抵御CSRF攻击有效的方法,因为攻击者无法猜出受害者的会话ID。但是,用户会话ID会在URL中出现。我们不建议为了修复一个安全漏洞而引入另一个。
HTTPS
HTTPS本身不抵御CSRF。
但是,HTTPS应该被是为任何预防措施值得信赖的前提。
举例
攻击是如何进行的
有大量欺骗用户从网站加载信息或发送信息给网站的方法。为了执行一次攻击,我们必须首先理解如何创建一个为我们用户而执行的有效的恶意请求。让我们考虑以下几个场景:alice使用bank.com网站想要转¥100给Bob,此网站容易受到CSRF攻击。攻击者Maria想欺骗Alice将钱转移给Maria。攻击将包括以下几步:
- 构建一个漏洞利用的URL或脚本
- 使用社工欺骗alice执行
GET场景
如果web应用被设计为主要使用GET请求去传递参数和执行行为,那么汇款操作可能被简化为一个请求,如:
GET http://bank.com/transfer.do?acct=BOB&amount=100 HTTP/1.1
Maria现状决定利用这个web应用的漏洞,将Alice作为受害者。Maria首先构建以下的漏洞利用URL,它将从Alice账户中转移¥100,000。Maria获得原始URL,并且替换收款人姓名为自己,同时大幅提高转移的金额:
http://bank.com/transfer.do?acct=MARIA&amount=100000
社工攻击Alice,让她在已登录此bank网站的时加载此URL。这通常能用以下技术中的一个完成:
- 发送带有HTML内容的未经请求的邮件
- 在受害者进行银行业务时,也可能访问的页面上植入漏洞利用URL或脚本。
漏洞利用URL能够伪装成普通链接,鼓励受害者点击。
<a href="http://bank.com/transfer.do?acct=MARIA&amount=100000">View my Pictures!</a>
或者作为一个 0x0的假图片(大小为0的图片):
<img src="http://bank.com/transfer.do?acct=MARIA&amount=100000" width="0" height="0" border="0">
如果这个图像标签包含在邮件中,Alice将看不到它。但是,浏览器仍然会提交此请求到bank.com,而看不到任何汇款执行的提示。
一个真实的使用GET方法攻击网站的CSRF例子是2008年的uTorrent exploit,它被用于大规模的下载恶意软件。
POST 场景
GET和POST攻击唯一不同点在于攻击时如何被用户执行的。让我们假设银行现状使用POST方法,并且漏洞请求如下:
POST http://bank.com/transfer.do HTTP/1.1
acct=BOB&amount=100
这类请求不能用一般的a或img标签传递,但能够通过form标签传递。
<form action="http://bank.com/transfer.do" method="POST">
<input type="hidden" name="acct" value="MARIA"/>
<input type="hidden" name="amount" value="100000"/>
<input type="submit" value="View my pictures"/>
</form>
这个表单要求用户点击submit按钮,但这也可以通过JS自动执行
<body onload="document.forms[0].submit()">
<form...
其他HTTP方法
现钉web应用API经常使用其他http方法,比如put或delete。让我们假设有漏洞的银行使用put方法,它需要一个json块作为参数。
PUT http://bank.com/transfer.do HTTP/1.1
{ "acct":"BOB", "amount":100 }
这类请求能够使用嵌入在漏洞利用页面的JS执行。
<script>
function put() {
var x = new XMLHttpRequest();
x.open("PUT","http://bank.com/transfer.do",true);
x.setRequestHeader("Content-Type", "application/json");
x.send(JSON.stringify({"acct":"BOB", "amount":100}));
}
</script>
<body onload="put()">
幸运的是,这个请求将不会在现代浏览器中执行,因为有同源策略的限制。这个限制默认开启,除非目标网站明确的打开来自攻击者(或任何人)的跨域请求,通过带有以下标头的CORS。
Access-Control-Allow-Origin: *