在现代web应用程序中的CSRF
作者:admin | 时间:2016-5-25 23:05:56 | 分类:黑客技术 隐藏侧边栏展开侧边栏
CSRF或跨站点请求伪造(Cross-Site Request Forgery)在2013年的OWASP的前十名排名中排第8名。
引用OWASP的一个关于CSRF的简短介绍:
跨站点请求伪造(CSRF)是一种迫使一个终端用户在web应用程序上执行其不想进行的操作的攻击,该操作迫使他们进行身份验证。此外,CSRF攻击特定目标的状态改变请求,并不窃取数据,因为攻击者无法看到伪造请求的响应。
所以,简单地说:
你可以精心制作一个HTTP请求,当它执行时可以执行一个状态改变的操作,比如改变受害者的电子邮件地址或密码,或购买东西;
这个操作是受害者采取的,而攻击者只负责影响受害者去发起请求。
正如它的名字所说,这是一个跨站点请求,即请求是从一个站点发送到另一个站点。这通常意味着攻击者无法控制这个请求实际上去了哪里,所以通常攻击者是不可能阅读跨站点响应消息的(SOP applies)。
引用Mozilla Developer Network的话:
同源策略限制了来自同一源头的一个文档或者脚本和来自另一源头的资源之间的相互作用,这是一个重要的用来隔离潜在恶意文件的安全机制;
然而,对攻击者而言,只需要这个操作被执行即可。浏览器收到服务器响应的时候,操作早已经完成。
今天的应用程序不仅仅回复URL 和 BODY参数,还大量使用HTTP头文件。让我们以Outlook为例:
一个简单的HTTP请求/响应可能看起来像这样的:
图中黄色高亮显示的HTTP头文件部分,经常X –开头的基本上是自定义标题,是服务器希望从每个请求中接收的。这里的X-OWA-CANARY是 ANTI-CSRF Token,它存在于HTTP头文件中,而不是BODY参数。我经常发现人们在检查CSRF时会忽略HTTP头文件,特别是对于初学者来说。如果服务器的配置是正确的,它将立即拒绝HTTP头文件中不含CSRF Token的请求,在这个例子中就是缺少X-OWA-CANARY,我们可以看到一个配置错误的诱饵的实现。
同时,人们缺乏“预检请求”的概念。在上面的例子中,即使服务器没有验证CSRF Token,我们也不能说它是易受CSRF攻击的——因为它可能使用了其他一些HTTP头文件,包含了“X-OWA-UrlPostData”,这是至关重要的。然而,可以设置自定义头文件来对跨站点请求做预检。
所以这到底是什么意思呢?
引用MDN的描述:
不像简单的请求,“预检请求”首先用设置的方法发送一个HTTP请求到另一个域的资源,以确定实际的请求发送是否是安全的。自从跨站点请求会影响到用户的数据之后一般都会做这样的预检。特别是,如果一个请求是以下这样就会做预检:
它使用了GET,HEAD 或者 POST以外的方法。此外,如果使用POST发送带有编码标签(Content-Type)而不是带有application/x-www-form-urlencoded, multipart/form-data, 或者 text/plain的请求数据,例如如果POST请求向服务器发送一个使用application / XML或text/ XML的XML有效负载,那么这个请求就需要进行预检;
它在请求中设置自定义头文件(例如使用一个带有X-PINGOTHER头文件的请求)。
简单地说,那些可能会给用户数据带来副作用的请求都需要进行预检。事实上,预检请求从来不会到达服务器,除非它们被明确告知。它们需要在相应的HTTP响应中出现特定的头文件信息。
如果想亲眼看一下,可以拷贝以下代码:
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://outlook.live.com/owa/service.svc?action=SubscribeToNotification&EP=1&UA=0&ID=-34&AC=1',true);
xhr.setRequestHeader('X-OWA-UrlPostData','%7B%22request%22%3A%7B%22__type%22%3A%22GetExtensibilityContextParameters%3A%23Exchange%22%2C%22FormFactor%22%3A3%2C%22ClientLanguage%22%3A%22en-US%22%2C%22IncludeDisabledExtensions%22%3Atrue%7D%7D');
xhr.send(null);
然后,粘贴到你的浏览器控制台(F12)。结果将是如下所示:
实际的请求应该是这样的:
恕我直言,使用HTTP头文件中带有anti-csrf令牌的应用(如Outlook、Instagram等)实际上并不容易遭受CSRF攻击,即使攻击者能够以某种方式计算CSRF Token。
总之,我想说:
有些人在检查CSRF攻击时只考虑anti-csrf Token。是的,虽然它可能在大多数情况下是脆弱的。但是,如果使用了一些猜不透的随机参数或者随机值的话,它并不是脆弱的。例如,在密码更改功能中anti-csrf令牌并不是必要的,如果它向你请求你现在的密码,那是因为攻击者需要你的密码来制作CSRF攻击你,这将使得他/她完全访问您的帐户。此外,在某些情况下,视图状态和时间戳值也为anti-csrf令牌的目的服务。所以,通常并不总是同样的token来阻止CSRF攻击,任何独一无二的或不可预测的/猜不透的键/值都可能阻止CSRF攻击。
这个帖子太长了,虽然我一直在努力压缩它。但是,我仍然相信我漏掉了很多东西,所以请为我提供宝贵的反馈信息。
不管怎样,我希望你们能够享受阅读这篇帖子。