CSRF漏洞的严重性在很大程度上取决于漏洞的位置。有时,错误的CSRF保护机制会导致无关紧要的问题,例如未经授权的设置更改或清空用户的购物车。有时,它们会导致更大的问题:用户信息泄漏,XSS甚至一键式帐户接管。
我在CSRF中遇到了一些导致严重安全问题的案例。通常,这些是CSRF和其他较小的设计缺陷的组合。
CSRF有时会导致信息泄漏。应用程序经常根据用户偏好发送或公开信息。如果这些设置端点没有受到CSRF的保护,则可以为敏感信息公开铺平道路。实现基于CSRF的信息泄漏的一种方法是处理这些请求。
例如,我曾经使用过的Web应用程序上的付费服务将每月的计费电子邮件发送到用户指定的电子邮件地址。这些电子邮件包括用户的街道地址,电话号码和有限的信用卡信息。可以通过以下请求更改发送这些计费电子邮件的电子邮件地址:
POST /change_billing_email
REQUEST BODY:
email=NEW_EMAIL &csrftok=12345
在此端点上的CSRF验证已损坏。服务器接受空白令牌,即使csrftok字段为空,请求也将成功。在使受害者发送以下请求后,所有以后的账单电子邮件都将发送到ATTACKER_EMAIL(直到受害者注意到未经授权的更改),从而将与该帐户关联的街道地址和电话号码泄露给攻击者。
POST /change_billing_email
REQUEST BODY:
email=ATTACKER_EMAIL &csrftok=
安全团队几乎总是将Self-XSS视为非问题,因为它们难以利用。但是,与CSRF结合XSS使用时,自身XSS通常可以变成存储的XSS。
例如,在我遇到的一个金融网站上,用户可以为每个链接的银行帐户创建昵称。帐户昵称字段容易受到XSS的攻击:该字段上的用户输入不进行清理,验证或转义。但是,这是只有授权用户才能编辑和查看的字段,因此攻击者无法直接触发XSS。
不幸的是,用于更改帐户昵称的终结点计算机上也存在CSRF错误。该应用程序未正确验证CSRF令牌的存在,因此仅在请求中省略令牌参数将绕过CSRF保护。例如:
POST /change_account_nickname
REQUEST BODY:
nickname= &csrftok=WRONG_TOKEN
该请求将失败。
POST /change_account_nickname
REQUEST BODY:
nickname=
虽然此请求将成功更改用户的帐户昵称,并存储XSS有效负载。下次用户登录帐户并查看其仪表板时,将触发XSS。
这些是我发现的一些最简单的帐户接管。这些情况也不少见。当帐户验证功能(如创建密码,更改密码,更改电子邮件地址或重置密码)中存在CSRF问题时,就会发生帐户接管问题。
例如,这是我在客户端的Web应用程序中发现的错误。
该网络应用程序允许社交媒体注册。用户通过社交媒体注册后,他们可以选择通过以下请求设置密码:
POST /password_change
REQUEST BODY:
oldpassword= &newpassword=XXXXX &csrftok=12345
由于用户通过其社交媒体帐户注册,因此不需要旧密码即可设置新密码。因此,如果CSRF保护在此终结点上失败,攻击者将能够为通过其社交媒体帐户注册但未设置密码的任何人设置密码。
不幸的是,这正是在此特定端点上发生的事情。应用程序无法正确验证CSRF令牌,并接受一个空值作为csrftok参数。因此,从本质上讲,以下请求会将任何人(尚未设置密码)的密码设置为ATTACKER_PASS。
POST /password_change
REQUEST BODY:
oldpassword= &newpassword=ATTACKER_PASS &csrftok=
现在,攻击者所需要做的就是将该请求嵌入到网站用户经常访问的页面上,并且她可以将访问这些页面的任何用户的密码自动分配给ATTACKER_PASS。之后,攻击者可以使用新分配的密码自由作为任何受害者登录。
CSRF非常普遍,非常容易利用。虽然我遇到的大多数CSRF都是低严重性问题,但有时对关键端点进行监督可能会导致严重后果。
如果您是开发人员,请特别注意部署在关键端点上的CSRF保护机制。