CSRF
Cross-site request forgery:跨站请求伪造
原理
攻击者利用受害者的身份,以受害者的名义执行非法操作。
举个例子,假如你想给某位用户转账100元,那么单击转账按钮之后,发出的HTTP请求会与http://www.xxbank.com/pay.php?user=xx&money=100类似。而攻击者构造链接(http://www.xxbank.com/pay.php?user=hacker&money=100),当受害者访问了该url后就会自动向Hack账号转账100元,而且这只涉及受害者的操作,攻击者没有获取受害者的cookie或其他身份信息。
攻击重点:
- 受害者登录了网站,能够执行网站的功能
- 受害者访问了攻击者的url
关键点
CSRF是一种欺骗受害者提交恶意请求的攻击,它继承了受害者的身份和特权信息,代表受害者执行非本意、恶意的操作。
对于大多数站点,浏览器请求自动发送关于该站点关联的的所有凭据,例如用户cookie信息、IP地址,Windows凭据等。因此,如果用户当前已对该站点进行了身份验证,则该站点无法区分受害者发送的伪造请求和受害者发送的合法请求。
目标
CSRF攻击目标是能够更改服务器状态或数据的业务或功能,例如更改受害者的电子邮件地址,密码或购买商品。
有时可以将CSRF攻击存储在易受攻击的站点上。这些漏洞被称为“存储的CSRF攻击”。这可以通过简单的HTML字段中存储在img或iframe标签中,或更复杂的跨站脚本攻击来实现。如果攻击可以在站点中存储CSRF攻击,则攻击的危害性将被放大。
触发
a标签的href属性
img标签的src属性
无论是GET方式还是POST方式,攻击者也可以通过构造表单的方式来伪造请求。
利用方法
- GET、POST链接操作
- 与XSS结合添加后台账户(创建AJAX请求)
<script>
xmlhttp = new XMLHttpRequest();
xmlhttp.open("post","http://xx.xx.xx.xx/xx.php","true");
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlhttp.send("action=addUser.php&username=hacker&password=123456")
</script>
将这段代码插入到网站留言板中,当管理员登录后查看到这条留言就可以创建一个账户。
防御
无效防御
- 使用加密cookie:所有的cookie都会随着每个请求一起提交攻击者并不获取受害者的cookie信息。
- 仅接收POST请求:POST请求同样可以伪造
- 多步交易:多步交易不足以预防CSRF攻击,只要攻击者可以预测或推断完整的事务步骤,就可以实现CSRF攻击
- URL重写:这可能被视为有效的CSRF防御技术,因为攻击者无法猜测受害者的会话ID。但是,用户的会话ID在URL中公开
- HTTPS:HTTPS本身无法防御CSRF。但是HTTPS应被视为任何防御措施的先决条件
有效防御
- 验证Referer字段。如果Referer是以自己的网站开头的域名,则说明该请求来自自身网站,是合法的,值得信赖。否则拒绝请求。
Referer字段存在被绕过的可能
- 添加token验证:在请求中加入攻击者不能伪造的信息,并且该信息不存在与cookie中。所以可以在HTTP请求中以参数的形式加入一个随机产生的token,并在服务器端验证token。如果请求中的token没有或者不正确则拒绝该请求。
- 二次验证:在执行转账等关键操作之前需要提供一个用户的密码进行二次验证,可以有效防御CSRF攻击。