浅谈原型污染

2025-02-27 41 0

什么是原型污染?

原型污染是一种JavaScript安全漏洞,它允许攻击者向全局对象原型中添加任意属性,这些属性随后可能会被用户定义的对象继承。
尽管原型污染本身通常无法作为独立漏洞被利用,但它允许攻击者控制那些原本无法访问的对象属性。如果应用程序随后以不安全的方式处理攻击者控制的属性,这可能会与其他漏洞串联起来。在客户端JavaScript中,这种情况通常会导致DOM型跨站脚本攻击(DOM XSS),而在服务器端,原型污染甚至可能引发远程代码执行。

原型污染漏洞是如何产生的?

原型污染漏洞通常发生在JavaScript函数将包含用户可控属性的对象递归合并到现有对象中时,而没有事先对键进行清理。这可能会让攻击者注入一个键名为__proto__的属性,以及任意嵌套的属性。

由于__proto__在JavaScript上下文中具有特殊含义,合并操作可能会将嵌套属性分配到对象的原型上,而不是目标对象本身。因此,攻击者可以通过注入包含恶意值的属性来污染原型,而这些属性可能会被应用程序以危险的方式使用。

虽然任何原型对象都可能被污染,但这种情况最常发生在内置的全局Object.prototype上。

成功利用原型污染漏洞需要以下关键要素:

  • 原型污染源——这是任何能够让你通过注入任意属性来污染原型对象的输入点。

  • 污染接收点(Sink)——换句话说,是一个能够导致任意代码执行的JavaScript函数或DOM元素。

  • 可利用的工具(Gadget)——这是任何未经适当过滤或清理就被传递到污染接收点的属性。

原型污染源

原型污染源是任何用户可控的输入,它允许你向原型对象中添加任意属性。最常见的来源包括:

  1. 通过查询字符串或片段字符串的URL

  2. 基于JSON的输入

  3. Web消息

通过URL的原型污染
考虑以下包含攻击者构造的查询字符串的URL:

https://vulnerable-website.com/?proto[evilProperty]=payload

当将查询字符串分解为键值对时,URL解析器可能会将__proto__解释为一个普通的字符串。但如果随后将这些键值对作为属性合并到一个现有对象中,情况会如何呢?

你可能会认为,__proto__属性及其嵌套的evilProperty属性,只是简单地被添加到目标对象中,如下所示:

{

​ existingProperty1: 'foo',

​ existingProperty2: 'bar',

proto: {

​ evilProperty: 'payload'

​ }

}

然而,事实并非如此。在某个时刻,递归合并操作可能会使用类似于以下语句的赋值操作来设置evilProperty的值:

targetObject.__proto__.evilProperty = 'payload';

在这个赋值过程中,JavaScript引擎将__proto__视为原型的访问器。因此,evilProperty会被赋值给返回的原型对象,而不是目标对象本身。假设目标对象使用默认的Object.prototype,那么在JavaScript运行时中,所有对象都将继承evilProperty,除非它们自身已经拥有一个同名的属性。

在实际中,注入一个名为evilProperty的属性不太可能产生任何影响。然而,攻击者可以利用相同的技术,用应用程序或任何导入的库所使用的属性来污染原型。

通过JSON输入的原型污染

用户可控的对象通常通过JSON.parse()方法从JSON字符串中生成。但是,JSON.parse()同样会将JSON对象中的任何键视为普通字符串,包括类似__proto__这样的键。这为原型污染提供了一个潜在的攻击向量。

假设攻击者通过Web消息注入以下恶意JSON,例如:

{

​ "proto": {

​ "evilProperty": "payload"

​ }

}

如果通过JSON.parse()方法将此内容转换为JavaScript对象,得到的对象实际上会有一个键为__proto__的属性。

const objectLiteral = {proto: {evilProperty: 'payload'}}; const objectFromJson = JSON.parse('{"proto": {"evilProperty": "payload"}}'); objectLiteral.hasOwnProperty('proto'); // false objectFromJson.hasOwnProperty('proto'); // true

如果通过JSON.parse()创建的对象随后在没有适当键清理的情况下被合并到现有对象中,这也会在赋值过程中导致原型污染,正如我们在前面基于URL的示例中所看到的那样。

原型污染接收点

原型污染接收点本质上是一个JavaScript函数或DOM元素,你可以通过原型污染访问它,从而执行任意JavaScript代码或系统命令。我们在关于DOM XSS的主题中已经详细讨论了一些客户端接收点。

由于原型污染让你能够控制那些原本无法访问的属性,这可能会让你接触到目标应用程序中的一些额外接收点。对原型污染不熟悉的开发人员可能会错误地认为这些属性不受用户控制,这意味着可能只会有很少的过滤或清理措施。

原型污染工具

原型污染工具(Gadget)是将原型污染漏洞转化为实际攻击的手段。它是指任何满足以下条件的属性:

  • 被应用程序以不安全的方式使用,例如在传递给接收点时未进行适当的过滤或清理。

  • 可通过原型污染被攻击者控制,即该对象能够继承攻击者添加到原型中的恶意版本的属性。

如果一个属性直接定义在对象本身上,那么它不能成为工具(Gadget),因为对象自身的属性版本会优先于你添加到原型中的任何恶意版本。一些健壮的网站可能会显式地将对象的原型设置为null,以确保它不会继承任何属性。

原型污染工具的示例

许多JavaScript库接受一个对象,开发人员可以使用它来设置不同的配置选项。库代码会检查开发人员是否明确向该对象添加了某些属性,如果是,则相应地调整配置。如果代表特定选项的属性不存在,通常会使用预定义的默认选项。一个简化的示例可能如下所示:

let transport_url = config.transport_url || defaults.transport_url;

现在想象一下,库代码使用这个transport_url来向页面添加一个脚本引用。

let script = document.createElement('script');

script.src =$


4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

恶意软件伪装成合法 Go 库感染Linux和macOS用户 | CSO Online
PWN栈溢出基础-ret2csu
【验证码逆向专栏】某盾 v2 滑动验证码逆向分析
探秘条件漏洞:系统安全的潜在隐患
记录某SRC邀请处逻辑越权到组织管理员漏洞
DNSTwist 使用指南

发布评论