javascript原型链污染攻击
在讲这个漏洞之前我们来理解一下Javascript。与其他的语言不同的是,Js在Es6之前是没有class的,他更多的是一个原型语言,在Js里有一句话很有名——“一切皆对象”。
什么是原型语言
1.只有对象,没有类;对象继承对象,而不是类继承类。
2.“原型对象”是核心概念。原型对象是新对象的模板,它将自身的属性共享给新对象。一个对象不但可以享有自己创建时和运行时定义的属性,而且可以享有原型对象的属性。
3.每一个对象都有自己的原型对象,所有对象构成一个树状的层级系统。root节点的顶层对象是一个语言原生的对象,只有它没有原型对象,其他所有对象都直接或间接继承它的属性。
关于Function.prototype和Object.__proto__
1.对象有__proto__属性,函数有prototype属性;
2.对象由函数生成;
3.生成对象时,对象的__proto__属性指向函数的prototype属性。
在没有手动修改__proto__属性的指向时,以上三条便是JavaScript默认原型链指向逻辑。如果要更形象的去理解这个就可以看下下图的这个结构:
什么是JavaScript原型链污染
原型链污染来自一个CVE(https://github.com/jquery/jquery/pull/4333),这个CVE是一个在jquery中修复的漏洞,但是这个漏洞广义的推广的话,受影响的范围应该是一切使用了ecmascript的应用,无论前后端。关于这个漏洞,是修复了jQuery的$.extend(true…)
方法,在jQuery中,这个方法用于将一个或多个对象的内容合并到目标对象。所以你永远不知道有不有人会不会写出一些类似以下的代码
当我们可控$.extend的参数的时候,我们就可以覆盖对象的__proto__或者prototype方法从而控制整个原型链的最顶端的方法,重写该方法将覆盖子对象或者函数的方法,从而导致污染原本的方法意图。
在npmjs官方搜下对象操作的库可以看到一大堆,例如“xtend
”、 “deepmerge
”、 “webpack-merge
”、 “merge2
”、 “lodash.merge
”。假如一些应用使用了这些方法,但是对参数没做任何处理。
漏洞范围影响
提出这个Javascript原型链污染攻击的作者写了一个pdf,在该pdf中,作者不仅做了漏洞的成因分析,还针对此漏洞做了受害范围分析,他在github上搜索了部分的组件,这些组件都是可以操作对象,一般都是对象合并操作的,较为底层,因此也会有大量的应用基于这些组件。例如“hoek”,“lodash”,“defaults-deep”等修复了这个原型链污染的可能性,当然还有一些组件他没统计到,例如“xtend”之类的,光weekly download的数量就有“12,097,425”。
笔者在npm上搜索了基于xtend的一些应用,找到一个language-exec这样的一个组件。这个组件是一个基于xtend的,不过这个组件好像年久失修而且没啥人用,看了源代码其中就有这样的一句话
可以看到类似的写法都是存在问题的(主要是我没找到具体的基于xtend的受影响应用)。
所以基于这个,大家不是有了刷CVE的思路了?没错…只要你敢花时间去爬全部的dependence就可以有机会获得javascript pollution attack CVE。
案例一远程命令执行
作者在github上搜到了一款叫做ghost cms的应用,当然这个漏洞已经修复,当黑客发送以下请求即可实现控制任意方法或者对象的任意属性。当然也就是rce了
在一切皆对象的JavaScript中,所有对象都可以调用toString和valueOf方法,当你通过__proto__重写这2个方法的时候,就容易在express等web框架中产生dos,导致服务无法正常运行。类似以下的写法就容易产生拒绝服务。
案例二DOS
在一切皆对象的JavaScript中,所有对象都可以调用toString和valueOf方法,当你通过__proto__重写这2个方法的时候,就容易在express等web框架中产生dos,导致服务无法正常运行。类似以下的写法就容易产生拒绝服务
案例三任意文件读取
如果你可以通过污染原型链来重写一些“私有属性”的话(Javascript没有私有属性),可能可以重写那些在WEB中用来定义渲染模板文件的属性值,就有可能产生任意文件读取了,如以下这个图片:
如何防御
在这里我们了解下这类攻击,如何从代码上更安全的编写,更好的防御这类漏洞。漏洞发现的作者给出了2个解决方案,先来看看我是如何防御的。
如果是我来解决这个问题的话,我会选择迭代对象的属性,直到查找到__proto__和prototype这2个属性名,如果出现就干掉。但是这个方法还是有缺陷,一个是建立于黑名单,需要列入的属性太多了,例如Dos的话就要把tostring和valueof等方法列入,而且遇到私有属性覆盖的话,怎么确保参数,接口很多。
原作者提出了3点:
1、使用Object.freeze来冻结对象,几乎所有的JavaScript对象都是Object的实例。所以冻结Object.prototype即可。具体大家可以去了解下es5就新增的Object.freeze方法,使用了这个方法,那么黑客就无法对prototype新增或者重写对应原型链上的方法,不过这样可能会导致一些隐性的bug产生,而且可能还不知道是哪里出错了。
2、用map数据结构来代替自带的对象结构。Es6就有map结构啦,这个map和Object的区别就是map的键可以是任意的对象类型,数组也好,对象也好。
3、使用Object.create(null)(强烈推荐), 使用这个方法就可以更好的防御原型链污染攻击了,因为Object.create(null)使得创建的新对象没有任何的原型链,是null的,不具备任何的继承关系,当你接受一个客户端的参数并且打算merge的话,可以使用此方法后去merge,这样的对象是比较安全的,客户端没办法通过原型链来污染攻击(因为压根就没原型链通往其他的对象)。我们可以简单的通过一个实验来看下。
相关文章教程推荐:web服务器安全
以上是javascript原型链污染攻击的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

用法:在JavaScript中,insertBefore()方法用于在DOM树中插入一个新的节点。这个方法需要两个参数:要插入的新节点和参考节点(即新节点将要被插入的位置的节点)。

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

JavaScript是一种广泛应用于Web开发的编程语言,而WebSocket则是一种用于实时通信的网络协议。结合二者的强大功能,我们可以打造一个高效的实时图像处理系统。本文将介绍如何利用JavaScript和WebSocket来实现这个系统,并提供具体的代码示例。首先,我们需要明确实时图像处理系统的需求和目标。假设我们有一个摄像头设备,可以采集实时的图像数
