客户端原型链污染漏洞
翻译
原文:https://portswigger.net/web-security/prototype-pollution/client-side
- name: 翻译
desc: 原文:https://portswigger.net/web-security/prototype-pollution/client-side
bgColor: '#F0DFB1'
textColor: 'green'
2
3
4
# 1客户端原型链污染漏洞
在本节中,你将学习如何在野外寻找客户端原型链污染漏洞。为了帮助你巩固漏洞工作原理,我们将介绍如何手动执行此操作,以及如何使用 DOM Invader 自动执行此过程。你还可以在一些故意易受攻击的LABS上利用 DOM型XSS (opens new window) 原型链污染来练习你所学到的知识。
# 2手动寻找客户端原型污染源
在很大程度上,人工寻找原型污染源是一个反复试错的过程。简而言之,你需要尝试用不同的方法去向Object.prototype
中添加任意属性,直到找到一段有效的源代码。
测试客户端漏洞时,这涉及以下高级步骤:
-
尝试通过查询字符串、URL 片段和任何 JSON 输入来注入任意属性。例如:
vulnerable-website.com/?__proto__[foo]=bar
1 -
在你的浏览器控制台中检查`Object.prototype`,查看它是否已经被任意属性污染:
Object.prototype.foo // 返回 "bar" 表示你已成功污染了原型 // 返回 undefined 表示攻击未成功
1
2
3 -
如果该属性未被添加到原型中,请尝试使用不同的技术,例如切换为 “点表示法” 而不是 “括号表示法”,反之亦然:
vulnerable-website.com/?__proto__.foo=bar
1 - 对每个潜在污染源重复以上过程。
提示
如果这两种技术都不成功,你仍然可以通过其 构造函数 来污染原型。我们稍后将会更详细地介绍这一点。
# 3使用DOM Invader查找客户端原型污染源
如你所见,手动寻找原型污染源可能是一个相当繁琐的过程。相反,我们建议你使用 DOM Invader,它被预装在了 Burp 的内置浏览器中。在你浏览网页时,DOM Invader 能够自动测试原型污染源,这可以为你节省大量时间和精力。有关更多信息,请查看 DOM Invader 的文档。
# 4手动寻找客户端原型污染小工具
当你识别了一个污染源 (opens new window),允许你向全局Object.prototype
中添加任意属性,下一步就是寻找一个合适的小工具,你可以利用这个工具来构造一个漏洞。在实践中,虽然我们建议使用 DOM Invader (opens new window) 来执行此操作,但了解手动执行过程非常有用,因为它有助于巩固你对漏洞的理解。
- 查看源代码,确定应用程序使用过的任何属性 或 导入的任何库。
- 在 Burp 中启用响应拦截(Proxy > Options > Intercept server responses)并捕获所测试 JavaScript 的响应包。
-
在脚本的开头添加
debugger
语句,然后转发任何剩余的请求和响应。 -
在 Burp 的浏览器中,转到加载目标脚本的页面。
debugger
语句将会暂停脚本的执行。 -
在脚本仍处于暂停状态时,切换到控制台并输入以下命令,将
YOUR-PROPERTY
替换为你觉得可能是小工具的潜在属性之一:Object.defineProperty(Object.prototype, 'YOUR-PROPERTY', { get() { console.trace(); return 'polluted'; } })
1
2
3
4
5
6该属性会被添加到全局
Object.prototype
中,每当访问它时,浏览器都会将 堆栈跟踪 记录到控制台。 - 点击按钮,继续执行脚本并留意控制台。如果出现堆栈跟踪,则可以确认 应用程序在某个位置访问了该属性。
- 展开堆栈跟踪,使用提供的链接 跳转到 读取了该属性的代码行。
-
使用浏览器的调试器控件,逐步执行每个流程阶段,以查看该属性是否有被传递到接收器中,例如
innerHTML
或eval()
。 - 对你认为 可能是潜在小工具的任何属性 重复以上过程。
# 5使用DOM Invader查找客户端原型污染小工具
从上面的步骤中可以看出,在野外手动识别原型污染小工具 可能是一项艰巨的任务。考虑到网站通常依赖于许多第三方库,这可能需要阅读数千行经过压缩 或 混淆的代码,这使得事情变得更加棘手。DOM Invader 可以代替你自动扫描小工具,在某些情况下甚至可以生成 DOM XSS 概念验证。这意味着,你可以在几秒钟内找到真实网站上的漏洞,而无需花上几小时。有关更多信息,请查看 DOM Invader 的文档。
- name: 实验室-从业者
desc: 客户端原型链污染-DOM型XSS >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/prototype-pollution/client-side/lab-prototype-pollution-dom-xss-via-client-side-prototype-pollution
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
- name: 实验室-从业者
desc: 备选原型链污染向量-DOM型XSS >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/prototype-pollution/client-side/lab-prototype-pollution-dom-xss-via-an-alternative-prototype-pollution-vector
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 6通过构造函数实现原型链污染
到目前为止,我们已经研究了如何通过特殊的访问属性__proto__
来获取对原型对象的引用。这是原型链污染的经典技术,一种常见的防御措施是在合并用户可控对象之前,从用户可控对象中剥离任何带有__proto__
键的属性。这种防御是有缺陷的,因为还有其他的方式,可以在不依赖__proto__
的情况下引用Object.prototype
。
除非将原型设置为null
(opens new window),否则每个 JavaScript 对象都会具有一个constructor
属性,该属性包含一个对构造函数的引用(哪个函数创建的这个对象,该引用就指向哪个函数)。例如,你既可以使用文字语法,也可以显式调用构造函数Object()
来创建一个新对象,如下所示:
let myObjectLiteral = {};
let myObject = new Object();
2
然后,你可以通过内置的constructor
属性来引用Object()
构造函数:
(译者加:这些对象是通过 “Object()” 函数创建出来的,所以这些对象的构造函数就会指向 “Object()”)
myObjectLiteral.constructor // function Object(){...}
myObject.constructor // function Object(){...}
2
请记住,函数也只是一个底层对象。每个构造函数都有一个prototype
属性,该属性指向这个构造函数的原型,此原型会分配给构造函数创建的任何对象。因此,你还可以通过以下方式,来访问任何对象的原型:
myObject.constructor.prototype // Object.prototype
myString.constructor.prototype // String.prototype
myArray.constructor.prototype // Array.prototype
2
3
由于myObject.constructor.prototype
等同于myObject.__proto__
,这为原型链污染提供了另一种攻击向量。
# 7绕过有缺陷的键清理
网站试图防止原型链污染的一个明显方法,在将属性键合并到现有对象之前,对其进行清理。但是,一个常见的错误 - 没有以递归方式清理字符串输入。例如,请考虑以下 URL:
vulnerable-website.com/?__pro__proto__to__.gadget=payload
如果清理过程只是简单的去除字符串__proto__
,而没有多次重复此过程,则会产生以下 URL,这是一个潜在的原型污染源:
vulnerable-website.com/?__proto__.gadget=payload
- name: 实验室-从业者
desc: 客户端原型链污染-绕过有缺陷的清理 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/prototype-pollution/client-side/lab-prototype-pollution-client-side-prototype-pollution-via-flawed-sanitization
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 8外部库中的原型链污染
正如我们已经提到的,原型污染小工具可能会出现在 应用程序导入的第三方库中。在这种情况下,我们强烈建议你使用 DOM Invader 的原型链污染功能,来帮助你识别污染源和小工具。这不仅要快得多,而且还能确保你 不会错过那些原本非常棘手的漏洞。
- name: 实验室-从业者
desc: 第三方库中的客户端原型链污染 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/prototype-pollution/client-side/lab-prototype-pollution-client-side-prototype-pollution-in-third-party-libraries
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
接下来呢?
PortSwigger Research 在浏览器广泛提供的 JavaScript APIs 中发现了许多原型污染小工具。了解这些功能,你将能够绕过针对 DOM型XSS 的脆弱原型链污染防御。