原型链污染攻击也称JavaScript Prototype 污染攻击

news2024/11/26 0:37:20

JavaScript数据类型

let和var关键字的区别

使用var或let关键字可以定义变量

let和var的区别如下:

    var是全局作用域,let 只在当前代码块内有效
    当在代码块外访问let声明的变量时会报错

    var有变量提升,let没有变量提升
    let必须先声明再使用,否则报Uncaught ReferenceError xxx is not defined;var可以在声明前访问,只是会报undefined

    let变量不能重复声明,var变量可以重复声明

普通变量
var x=5;
var y=6;
var z=x+y;
var x,y,z=1;

let x=5;
数组变量
var a = new Array();

var a = [];

字典
var a = {};
var a = {"foo":"bar"};
JavaScript函数
在Javascript中,函数使用function关键字来进行声明
function myFuntion() {

}
声明带参数的函数
function myFuntion(a) {
	
}
声明带返回值的函数
function myFuntion(a) {
	return a;
}
直接调用匿名函数

(function(a){
    console.log(a); 
})(123);
还可以把变量变成函数,调用fn()即调用了匿名函数的功能

var fn = function(){
    return "将匿名函数赋值给变量";
}

 假设在函数内部新建了一个变量,函数执行完毕之后,函数内部这个独立作用域或(封闭的盒子)就会删除,此时这个新建变量也会被删除。

如何令这个封闭的盒子是不会删除?可以使用“闭包”的方法(闭包涉及函数作用域、内存回收机制、作用域继承)

闭包后,内部函数可以访问外部函数作用域的变量,而外部的函数不能直接获取到内部函数的作用域变量

例如不使用额外的全局变量,实现一个计数器

因为add变量指定了函数自我调用的返回值(可以理解为计数器值保存在了add中), 每次调用值都加一而不是每次都是1

var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();

JavaScript类

在以前,如果要定义一个类,需要以定义“构造函数”的方式来定义,例如

function newClass() {
    this.test = 1;
}

var newObj = new newClass();

如果想添加一些方法呢?可以在内部使用构造方法

function newClass() {
    this.test = 123;
    this.fn = function() {
        return this.test;
    }
}

var newObj = new newClass();
newObj.fn();

为了简化编写JavaScript代码,ECMAScript 6后增加了class语法

class 关键字

可以使用 class 关键字来创建一个类

形式如下(如果不定义构造方法,JavaScript 会自动添加一个空的构造方法)

class ClassName {
  constructor() { ... }
}

class myClass {
  //newClass的构造方法如下
  constructor(a) {
    this.test = a;//含有一个test属性,值为构造时传入的参数
  }
}

使用new创建对象

let testClass = new myClass("testtest");

查看testClass对象的test属性的值,为testtest

往对象添加属性

直接使用.属性名即可,例如向testClass添加aaa属性

testClass.aaa = 333;

类的方法

形式如下

class ClassName {
  constructor() { ... }
  method_1() { ... }
  method_2() { ... }
  method_3() { ... }
}

/*
* 引入express框架,使用require函数传递形参 'express' 进行引入,
* 其实在 let 的后面的名称可以自己定义即可
*/
let express = require('express');

/*
* 使用引入进来的express框架的变量名express来构建一个web服务器实例,
* 名叫myWeb,也可自定义实例名称
*/
let myWeb = new express();

/*
* 往实例 myWeb 的调用函数use传入指定的网络路径和自己编写的响应中间件(其实就是一个函数),
* 这就是服务器的接口的编写方式
*/
myWeb.use("/",function(req,res){
    res.send("Hello, NodeJS and express!");
    res.end();
});

/*
* 调用listen函数,传递好服务器要用的端口号,一般尽量不是电脑操作系统保留范围的端口号即可,
* 8080就是这个服务器的端口号
*/
myWeb.listen(8080,function(){
    //这里可以输入服务器启动成功后要执行的代码,如启动是否成功等终端输出提示,一般这个回调函数可有可无

});

原型链污染

什么是原型

这里的原型指的是prototype

比如说上面前言部分讲的JavaScript类那里,

我们使用new新建了一个newClass对象给newObj变量

function newClass() {
    this.test = 1;
}

var newObj = new newClass();

实际上这个newObj变量使用了原型(prototype)来实现对象的绑定【而不是绑定在“类”中,与JavaScript的特性有关,它的“类”与其它语言(例如JAVA、C++)类不同,它的“类”基于原型】

prototype是newClass类的一个属性,而所有用newClass类实例化的对象,都将拥有这个属性中的所有内容,包括变量和方法,如下

 

简单来说就是:

    prototype是newClass类的一个属性
    newClass类实例化的对象newObj不能访问prototype,但可以通过.__proto__来访问newClass类的prototype
    newClass实例化的对象newObj的.__proto__指向newClass类的prototype

关系如下

原型链污染原理
原理

现在已经知道实例化的对象的.__proto__指向类的prototype,

那么修改了实例化的对象的.__proto__的内容, 类的prototype的内容是否也会发生改变?

答案是肯定的,这就是原型链污染的利用方法

比如说现在有一个类a

function a() {
    this.test = 1;
}

var obj = new a();

修改a类的原型(即Object,如本文什么是原型部分-关系如下所示),

添加一个属性test1,令其值为123

a.prototype.test1 = 123;

再次查看obj的内容,多了一个test1

访问下obj.test1看看

然后尝试通过obj1的.__proto__属性来修改test1的值

obj1.__proto__.test1 = 124;

此时访问obj.test1,发现也被修改成了124

明明没有动obj,obj.test1却改变了,说明a类中的test1被修改了

obj.test1

查看a类的属性,确实如此

通过obj1中.__proto__属性添加一个新属性,和上面修改a类的原型的过程也是一样的

下面演示添加新属性test2

obj1.__proto__.test2 = 111;

如下图操作所示

可以发现obj中也出现了新属性test2, 并且a类中也出现了新属性test2

进一步利用

上面的例子中,展示了如何通过对象往类中添加一个新属性并修改这个新属性

那如果想改变已有属性的值呢?

先实例化一个字典对象,叫obj,内有key名为test,test的value是123

var obj = {"test": 123};

然后通过obj的.__proto__属性为test重新赋值

obj.__proto__.test = 2;

再实例化一个空字典对象,叫ooo

var ooo = {};

查看ooo的test属性,发现居然是2

因为Object类的test属性已经被污染,而对象ooo和obj同属Object类

那再看看obj的test属性的值,为123

这是为啥?

这就涉及到查找顺序了

查找顺序
描述

关于查找顺序,我觉得我无法写出比P神更好的解释,所以这里直接引用P神的解释

所有类对象在实例化的时候将会拥有prototype中的属性和方法,这个特性被用来实现JavaScript中的继承机制。
function Father() {
    this.first_name = 'Donald'
    this.last_name = 'Trump'
}

function Son() {
    this.first_name = 'Melania'
}

Son.prototype = new Father()

let son = new Son()
console.log(`Name: ${son.first_name} ${son.last_name}`)
Son类继承了Father类的last_name属性,最后输出的是Name: Melania Trump。

总结一下,对于对象son,在调用son.last_name的时候,实际上JavaScript引擎会进行如下操作:

    在对象son中寻找last_name
    如果找不到,则在son.__proto__中寻找last_name
    如果仍然找不到,则继续在son.__proto__.__proto__中寻找last_name
    依次寻找,直到找到null结束。比如,Object.prototype的__proto__就是null

更多描述

比如说此处的obj

利用.__proto__修改值后的test属性在当前对象的test属性下面(也就是在当前对象所绑定的prototype中),

所以优先读取当前对象下的test属性,即未被修改的值123

而ooo对象由于当前属性中没有test属性,只能从它绑定的prototype中找test对象(或下一级的prototype),

没找到返回undefined

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1565535.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文秒解四大经典限流算法

阅读前提:没有最好的算法,只有最适合的算法! 限流算法: 固定窗口限流算法 滑动窗口限流算法 漏桶限流算法 令牌桶限流算法 固定窗口限流算法 介绍 固定窗口限流算法(Fixed Window Rate Limiting Algorithm&#…

算法知识点汇总

知识点 1. 求二进制中1的个数 int get_count(int x)//返回x的二进制有多少个1 int get_count(int x) {int res 0;while (x){res ;x - x & -x;}return res; }2. 建树,和树的DFS 记得初始化头节点 const int N 1e5 10, M N * 2; int h[N], e[M], ne[M], id…

【OpenCV】 基础入门(一)初识 Mat 类 | 通过 Mat 类显示图像

🚀 个人简介:CSDN「博客新星」TOP 10 , C/C 领域新星创作者💟 作 者:锡兰_CC ❣️📝 专 栏:【OpenCV • c】计算机视觉🌈 若有帮助,还请关注➕点赞➕收藏&#xff…

OR-352,兼容替代TLP187/TLP127/EL452等,达灵顿光耦

低输入正向电流 高电流传输比 DC和AC输入 电平转换 高输入输出隔离电压和高集电极发射极电压 特征 电流传输比(IF 1mA,VCE 2V时,CTR : 最小1000%) 高集电极-发射极电压 (VCEO 300V) …

mongodb的简单操作

文章目录 前言数据库的创建和删除集合的创建和删除文档的插入和查询异常处理更新数据局部修改符合条件的批量更新加操作 删除文档删除全部数据删除符合条件的数据 统计count统计有多少条数据统计特定条件有多少条数据 分页查询排序查询正则查询比较查询包含查询条件连接查询索引…

Python疑难杂症(16)---Numpy知识集合(四)列出Numpy模块的常用函数,供查询参考。

列出Numpy模块的常用函数,供查询参考。 numpy.array:创建新的NumPy数组 numpy.zeros:创建一个以零填充的数组。 numpy.random:生成随机数组的函数。 numpy.linspace:在指定范围内生成均匀间隔的数字。 numpy.range:用间隔的值创建数组。 numpy.shape:返回一个…

AWS-EKS 给其他IAM赋予集群管理权限

AWS EKS 设计了权限管理系统,A用户创建的集群 B用户是看不到并且不能管理和使用kubectl的,所以我们需要共同管理集群时就需要操场共享集群访问给其他IAM用户。 两种方式添加集群控制权限(前提:使用有管理权限的用户操作&#xff…

睡岗检测识别系统

智驱力睡岗检测识别系统是一种基于人工智能技术的监控系统,旨在通过视频分析来识别和报警那些在工作岗位上出现睡觉行为的人员。这种系统通常应用于需要24小时监控的关键岗位,如银行、营业厅、监控中心等场所。系统能够自动分析监控画面,当检…

如何在比特币上验证ZK Proofs

1. 引言 前序博客有: 基于BitVM的乐观 BTC bridgeBitVM:Bitcoin的链下合约Bitcoin Bridge:治愈还是诅咒?BitVM2:比特币上的无需许可验证以比特币脚本来实现SNARK VerifierClementine:Citrea的基于BitVM的…

鸿蒙HarmonyOS应用开发之NativeBundle开发指导

场景介绍 开发者可以通过本指导了解在OpenHarmony应用中,如何使用Native Bundle接口获取应用自身相关信息。 接口说明 开发步骤 1. 创建工程 2. 添加依赖 创建完成后,IDE会在工程生成cpp目录,目录有libentry/index.d.ts、hello.cpp、CMak…

XenCenter 2024 导入虚拟机

导入虚拟机 虚拟机位置 导入到那一个服务器 导入虚拟机存放存储位置 虚拟机网卡配置 SR修复功能,看自己需求 虚拟机恢复确认最终配置 恢复好的虚拟机 虚拟机模板转换

上位机图像处理和嵌入式模块部署(qmacvisual图像清晰度)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 做过isp的同学都知道,图像处理里面有一个3A,即自动曝光、自动白平衡和自动对焦。其中自动对焦这个,就需要用输入…

HbnnMall电子商城系统介绍(功能与技术栈)

今天在看自己网站上的文章时,看到了曾经开发的电商系统。那是在2020年,来到小米两年后,我已经对各个业务线,各种专业知识有了系统性的了解和学习,所以想自己动手写一个电商系统,以便进一步提高自己的技术。…

【数论】莫比乌斯反演(欧拉反演)进阶-杜教筛

文章目录 前言 回忆 题集12 杜教筛例题 前言 这里需要对莫反有一些基础。 不会的可以点这里 回忆 f ( n ) ∑ d ∣ n g ( d ) → g ( n ) ∑ d ∣ n f ( d ) μ ( n d ) f(n)\sum_{d|n}g(d)\rightarrow g(n)\sum_{d|n}f(d)\mu(\frac{n}{d}) f(n)∑d∣n​g(d)→g(n)∑d∣n​…

vue3+eachrts饼图轮流切换显示高亮数据

<template><div class"charts-box"><div class"charts-instance" ref"chartRef"></div>// 自定义legend 样式<div class"charts-note"><span v-for"(items, index) in data.dataList" cla…

unity之 “Allow ‘unsafe‘ code“ 在哪里。

导入unity中的代码&#xff0c;出现如下错误&#xff0c;该如何解决&#xff1f; Unsafe code may only appear if compiling with /unsafe. Enable "Allow unsafe code" in Player Settings to fix this error 解决这个问题&#xff0c;只需要设置就可以。 设置的地…

【苍穹外卖】log爆红

使用了Slf4j注解&#xff0c;用于自动生成一个log对象&#xff0c;相当于private final Logger log LoggerFactory.getLogger(当前类名.class); 这个注解需要安装Lombok插件才能使用。 IDEA file—settings–plugins&#xff0c;搜索lombok–install。安装完后自动重启IDEA后…

【WEEK6】 【DAY2】DQL Data Querying - Part Two 【English Version】

2024.4.2 Tuesday Following the previous article 【WEEK6】 【DAY1】DQL Data Query - Part One【English Version】 Contents 4.4. Join Queries4.4.1. JOIN Comparison4.4.2. Seven Types of JOINs4.4.3. Examples4.4.3.1. In this example, the results of INNER JOIN and…

DLL导出API注意事项

文章目录 问题原则示例一解决方案 示例二解决方法 参考 问题 在 windows 平台下&#xff0c;如果在动态库的接口中使用 std::string 或其它 std 容器&#xff0c;会导致崩溃或其它内存问题&#xff0c;所以一般要求动态库的接口必须是 C 语言实现。 原则 一个原则&#xff1a;…

LabVIEW专栏二、调用子VI

该节目标是创建带子vi&#xff0c;修改vi属性&#xff0c;测试可重入和不可重入的区别 一 、设置子VI 把VI封装成为子VI&#xff0c;可以帮助模块化程序&#xff0c;简化代码结构。 任何VI本身都可以成为别的VI的子VI。 1.1、设置输入输出端子 1、在前面板空白处&#xff0…