2.1 开放式重定向如何工作
开放式重定向一般发生在开发者误信了攻击者控制的输入而将网站重定向到另一个站点,这通常是通过URL参数、HTML<meta>刷新标签、DOM(Document Object Model,文档对象模型)中window对象的location属性等实现的。
很多Web网站都是通过在原始URL的参数中设置目标URL来有意实现用户访问的重定向的。应用程序通过使用这个参数来告诉浏览器向目标URL发送一个GET请求,例如,假定Google网站具有重定向到Gmail的功能,就可以通过访问如下URL实现:
在这种情况下,当我们访问上面的URL时,Google网站会接收到一个HTTP的GET请求,然后依据redirect_to参数中指定的值来确定将你的浏览器重定向到哪里。在这之后,Google网站服务器会返回一个用于指示浏览器重定向用户的HTTP响应状态码。通常,这个状态码是302,但有时也可能是301、303、307或308。这些HTTP响应状态码告诉浏览器请求的网页找到了,但是需要浏览器发起一个GET请求到redirect_to参数值,https://www.gmail.com/这个参数值也在HTTP响应Location头中。Location头表示了向哪里重定向GET请求。
现在,假设攻击者修改了原始的URL,如下所示:
如果Google没有验证redirect_to参数是否为其将访问者重定向到一个自有合法站点,攻击者就可以将该参数的值换成它们自己的URL。结果是,HTTP响应可能会引导浏览器向https://www.<attacker>.com/发起GET请求。一旦攻击者已经引导用户到他们的恶意网站,就可以发起进一步的攻击。
当检查这类漏洞时,要重点关注具有特定名称的URL参数,例如url=、redirect=、next=等,因为这些都有可能会表示引导用户重定向去的URL。另一个需要注意的是,重定向参数不总是明显命名的,参数也可能随着网站的不同而不同,即使同一个网站内部不同的链接时也可能不同。在有些情况下,参数可能以单个字母的形式表示,例如r=或u=等。
除了基于参数的攻击之外,HTML<meta>标签和JavaScript都可以重定向浏览器。HTML<meta>标签可以告知浏览器刷新网页,并向标签中的content属性定义的URL发起GET请求。下面是一个例子:
content属性定义了浏览器发起HTTP请求的两个步骤。首先,content属性定义了浏览器在向URL发起HTTP请求前需要等待的时间,在本例中,这个时间是0秒。其次,content属性确定了浏览器向其发起GET请求的网站中URL的参数,在本例中,这个参数是https://www.google.com。当攻击者具有控制<meta>标签的content属性的能力时,或者通过其他漏洞能够注入他们自己的标签时,就可以利用这种重定向行为。
攻击者还可以通过使用JavaScript修改文档对象模型(DOM)中window对象的location属性来实现重定向用户。DOM是用于HTML和XML文档的API,它允许开发者修改网页的结构、风格和内容。因为location属性表示了请求将被重定向到哪里,浏览器将立刻解释JavaScript脚本并重定向到指定的URL。攻击者可以通过如下形式的JavaScript脚本修改window的location属性:
通常,仅当攻击者能够执行JavaScript语句时才能设置window.location的属性值,而获得JavaScript执行权限一般是通过跨站脚本漏洞或者网站允许用户自定义重定向URL的漏洞来实现,就像在本章介绍的HackerOne中间网页重定向漏洞一样。
当挖掘开放式重定向漏洞时,你通常需要持续监测发向测试网站的包含URL重定向参数的GET请求代理历史。