用Origin请求头防御CSRF攻击(译文)

其实是为迎战第二天英语竞赛而翻译的文章_(:з」∠)_

原文链接:http://www.sjoerdlangkemper.nl/2019/02/27/prevent-csrf-with-the-origin-http-request-header/

HTTP请求中的Origin请求头表示请求的来源,可以对防御跨站请求伪造攻击起到作用。

跨站请求

有些跨站请求是正常的,比如从另一个域调用图片等。但你一定不想将包含一些信息的认证请求呈现给另一个域,也就是CSRF。确定哪个页面发出请求对于积极防御CSRF攻击是很有用的,如果一个站点能确定请求来自哪里,它就能过滤请求。Referer头会包含这个信息但它是不可靠的,Origin头才是将这个信息添加到请求的可靠方式。

Referer请求头

Referer头是一个较古老的请求头,包含了用户来源URL,当你点击一个链接时,当前页面的URL会被发送到这个链接。也就是说,这可以用于确定用户来自哪里,从而帮助我们阻止跨站请求。然而Referer头存在两个问题。

第一,Referer头不够详尽。哪个请求应该发送Referer,甚至究竟是否该发送这个请求头都未被清楚说明。即使大多数浏览器确实发送了这个请求头,它们也并没有这样做的依据。

第二,Referer请求头会泄露整个URL给别的域。如果URL包含一些session token或其他敏感数据,用户点击链接发送的Referer头将会将这些数据发送出去。这也是为什么许多反病毒方案会将HTTP请求中的Referer请求头直接去掉,以防止URL泄露敏感数据,因此我们并不能依赖Referer头。

Origin请求头

Origin请求头只包含URL的格式、主机名和端口,也就避免了URL参数泄露给其他主机,虽然仍旧可以看出请求的来源。请求头看起来大概像这样:

Origin: https://www.sjoerdlangkemper.nl

根据说明文档,HTTP请求可以包含多个Origin头,虽然我还没见过浏览器这样使用。还存在一个特殊的null值来表明这个来源是不可靠的。

null值

如果文本不存在清晰的源,或请求根本不可信,不需要考虑源,null就可以用来表示。

在一些情况下,字符串”null”会替代来源信息被发出,这样做是为了表明请求是不可信的,即使它是同源请求。某些请求在变化的触发条件下[…]未必总有用,而且可能并不可信,即使来自同一个源。

浏览器会使用null Origin,比如iframe + data URL的例子:

<iframe src="data:text/html,<form method="POST"...

现代浏览器认为Data URLs是唯一不透明的源而不是继承包含页面的源。这说明data URL的源从不可靠,而null Origin就是被用来表明这一点的。

浏览器差异

即使Origin的文档描述了这个请求头并且指明了一些用法,它也并没有定义好什么时候包含Origin头或Origin的期望值。Chrome和Firefox都在JavaScript POST请求中包含了Origin头,这些请求的行为和其他都不相同。Origin请求头被包含在:

  • Chrome的所有POST表单,Firefox的则没有
  • Firefox的所有JavaScript Fetch请求,Chrome中不包含HEAD和GET
  • 跨域重定向,Firefox使用来源域作为Origin而Chrome使用null Origin

用这个样例页面观察你的浏览器行为。

这些差异使得目前origin请求头的使用比较有限,不能依赖Origin头呈现在特定种类请求中,也就限制了防御的深度:在它呈现时检测它,但不要依赖它。

结论

检测Origin请求头是一个良好的额外防御跨站请求伪造及相关攻击的方式,虽然它已经被应用在浏览器中,但他的行为定义还没有完善到能依赖Origin头在特定请求中呈现。

相关阅读

文章目录
  1. 1. 跨站请求
  2. 2. Referer请求头
  3. 3. Origin请求头
    1. 3.1. null值
  4. 4. 浏览器差异
  5. 5. 结论
  6. 6. 相关阅读
|