在URL凭据中隐藏Payload | PortSwigger研究
去年,Johan Carlsson发现可以在URL的凭据部分隐藏Payload。这一点特别吸引我,因为Payload在Chrome和Firefox的URL中实际上不可见,甚至在同源导航中仍然保持隐藏。像一只咬住骨头的狗一样,我不肯放手,试图探索可能的应用…
第一个令我惊讶的是,document.URL并不总是与location匹配。例如:
|
|
我原本以为这两个属性是相同的,因为我从未观察到它们有差异,但事实证明,document.URL包含URL的凭据部分,而location不包含。这意味着你可以在事件中使用URL,从凭据中提取Payload:
|
|
从凭据中提取Payload
在模糊测试以识别URL凭据部分哪些字符被编码后,Shazzer发现Firefox不对单引号进行URL编码。这在DOM XSS场景中特别有用,尤其是当网站移除查询字符串和哈希时。这使得如下漏洞在Firefox中可被利用:
|
|
要利用这一点,你需要在Firefox的凭据部分提供Payload,如下所示:
|
|
这可以通过重定向或用户导航来传递。你甚至可以使用这种技术来控制锚链接的username或password属性。这是因为每个锚元素都有这些属性,它们存储来自URL的凭据。如果是相对链接,它会继承父凭据,允许你覆盖这些值:
|
|
锚覆盖示例
你可以将此与DOM覆盖结合,以控制具有username或password属性的对象。注意,你甚至可以提供一个空的href,仍然可以通过URL控制username或password。
|
|
总之,发现location和document.URL之间的差异,以及document.URL如何保留URL的凭据部分——即使Chrome和Firefox等浏览器在地址栏中隐藏它——是相当令人惊讶的。Firefox对某些字符(如单引号)的处理(不进行URL编码)也可能对DOM XSS有用。
通过凭据隐藏Payload、操纵锚元素内的username和password属性,并可能将其与DOM覆盖结合的能力,可以用于更高级的利用。
注意:Safari会丢弃URL凭据。所有示例仅适用于Chrome和Firefox。此外,Chrome阻止子资源使用URL凭据。