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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

U-net在乳腺癌医学图像分割方面的应用

图像几何变换和生成对抗网络 通过旋转、反转、剪切图像对乳腺医学图像进行数据增强之后,可以提高模型的准确性。但是当前简单的分割和几何变换在医疗图像数据中不会简单使用,而是会集合生成对抗网络(GAN)结合使用。使用生成对抗网…

zookeeper监听集群节点的实现zkclient组件实现方案(Java版)

ZooKeeper Watcher 机制 client 向zookeeper 注册监听client注册的同时会存储一个WatchManager对象向zookeeper发生改变则notification client 并发送一个WatchManager对象,然后client再更新该对象 package com.jacky.zk.demo;import org.I0Itec.zkclient.IZkChildListener;…

https访问http的minio 图片展示不出来

问题描述:请求到的图片地址单独访问能显示,但是在网页中展示不出来 原因:https中直接访问http是不行的,需要用nginx再转发一下 nginx配置如下(注意:9000是minio默认端口,已经占用,…

基于Spring Boot的餐厅点餐系统

基于Spring Boot的餐厅点餐系统 开发语言:Java框架:springbootJDK版本:JDK1.8数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9 部分系统展示 管理员登录界面 用户注册登录界面 …

MySQL-视图:视图概述、创建、查看、更新、修改、删除

第14章 视图 1. 常见的数据库对象2. 视图概述2.1 为什么使用视图?2.2 视图的理解 3. 创建视图3.1 创建单表视图3.2 创建多表联合视图3.3 基于视图创建视图 4. 查看视图5. 更新视图的数据5.1 一般情况5.2 不可更新的视图 6. 修改、删除视图6.1 修改视图6.2 删除视图 …

uniapp微信小程序真机图片不显示

不同设备可能出现部分设备显示不了图片,解决办法:图片地址直接使用,不要拼接: https://images.weserv.nl/?urlhttp

hive 慢sql 查询

hive 慢sql 查询 查找 hive 执行日志存储路径(一般是 hive-audit.log ) 比如:/var/log/Bigdata/audit/hive/hiveserver/hive-audit.log 解析日志 获取 执行时间 执行 OperationId 执行人 UserNameroot 执行sql 数据分隔符为 \001 并写入 hiv…

【Java】:继承

目录 1.为什么需要继承 2.继承的概念 3.继承的语法 4.父类成员访问 4.1子类和父类不存在同名成员变量 1.子类和父类不存在同名成员变量 2.子类和父类成员变量同名 4.2子类中访问父类的成员方法 1.成员方法名字不同 2.成员方法名字相同 5.super关键字 6.子类构造方法 …

使用Flutter创建带有图标提示的TextField

在移动应用开发中,TextField是一种常用的用户输入小部件。然而,有时向用户提供有关他们应该输入什么的提示或说明是很有帮助的。在本教程中,我们将创建一个Flutter应用程序,演示如何在TextField旁边包含一个图标提示。 编写代码 …

WPS二次开发系列:如何获取应用签名SHA256值

在申请WPS SDK授权版时候需要开发者提供应用包名和签名,应用包名好说,那如何生成符合WPS要求的应用签名(SHA256)呢,经笔者亲测,有如下两种方式可以实现获取第三方应用签名值(SHA256) 1. 方法一&…

Day43 动态规划 part05

Day43 动态规划 part05 1049.最后一块石头的重量II 我的思路: 提示说和划分两个和相等的子集差不多,猛然想到,这道题不就是划分子集,用sum - 和最大*2 代码就是划分和相同的子集的变形 解答: class Solution {public int last…

一站式指南:Flutter应用如何顺利登陆苹果App Store

引言 🚀 Flutter作为一种跨平台的移动应用程序开发框架,为开发者提供了便利,使他们能够通过单一的代码库构建出高性能、高保真度的应用程序,同时支持Android和iOS两个平台。然而,完成Flutter应用程序的开发只是第一步…

Spring Boot 学习(1)——环境搭建

一只老辣鸟的自我救赎 不科普,简单记录学习过程。 开发环境约束: jdk1.8 Spring Boot 1.5.9 Spring 4.3.13 Maven 3.3.3 Intellij IDEA 2017 【脑瓜灵光的开发环境随意,不灵光尽量按上述约束设置。看了好些教程总…

商务电子邮件: 在WorkPlace中高效且安全

高效和安全的沟通是任何组织成功的核心。在我们关于电子邮件类型的系列文章的第二期中,我们将重点关注商业电子邮件在促进无缝交互中的关键作用。当你身处重要的工作场环境时,本系列的每篇文章都提供了电子邮件的不同维度的视角。 “2024年,全…

从开放GPT3.5看大模型发展

当地时间周一(4月1日),人工智能(AI)公司OpenAI宣布,将允许用户直接使用ChatGPT,而无需注册该项服务,这将让人们更加容易体验人工智能的潜力。 图片来源:OpenAI官网截图 OpenAI表示,它将从周一开始逐步推出…

tomcat-连接器架构设计

一、NioEndpoint组件 Tomcat的NioEndPoint组件实现了I/O多路复用模型,接下来我会介绍NioEndpoint的实现原理。 1.总体工作流程 我们知道,对于Java的多路复用器的使用,无非是两步: 1.创建一个Seletor,在它身上注册各…

asf是什么格式的文件?用手机怎么打开?

由于手机操作系统和硬件的限制,大部分手机并不直接支持asf文件的播放。因此,如果你想在手机上打开asf文件,你可能需要先将文件转换为手机支持的格式,如MP4。可以通过使用一些视频转换软件来实现,比如野葱视频转换器。 …

docker容器技术篇:Docker API配置与常用操作

docker容器技术篇:Docker API配置与使用 一、API具体是什么? 百科解释应用程序接口(API),又称为应用编程接口,就是软件系统不同组成部分衔接的约定,蒙了吧!!&#xff0…

docker部署nacos,单例模式(standalone),使用mysql数据库

文章目录 前言安装创建文件夹"假装"安装一下nacos拷贝文件夹删除“假装”安装的nacos容器生成nacos所需的mysql表获取mysql-schema.sql文件创建一个mysql的schema 重新生成新的nacos容器 制作docker-compose.yaml文件查看网站 前言 此处有本人写得简易版本安装&…

目标检测——图像中提取文字

一、重要性及意义 图像提取文本,即光学字符识别(OCR)技术,在现代社会中的重要性和意义日益凸显。以下是关于图像提取文本的重要性和意义的几个关键方面: 信息获取的效率提升 快速处理大量文档:OCR技术可…