某不知名博客 某不知名博客
首页
  • 《vulcat文档》
  • Web安全

    • 《BurpSuite及官方实验室》
    • 《OSWE学习历程》
  • 云原生安全

    • 《Docker命令大全》
    • 《CKS考试学习指南》
    • 《旧-Kubernetes教程》
漏洞库
  • 《渗透工具大全》
  • 《云安全》
事件库
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carsaid

安全界的小学生
首页
  • 《vulcat文档》
  • Web安全

    • 《BurpSuite及官方实验室》
    • 《OSWE学习历程》
  • 云原生安全

    • 《Docker命令大全》
    • 《CKS考试学习指南》
    • 《旧-Kubernetes教程》
漏洞库
  • 《渗透工具大全》
  • 《云安全》
事件库
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 前言

  • 服务器端主题(翻译)

  • 客户端主题(翻译)

  • 高级主题(翻译)

    • 高级主题
    • 不安全的反序列化

    • Web LLM攻击

    • GraphQL API漏洞

    • 服务端模板注入

    • Web缓存投毒

    • HTTP主机头攻击

    • HTTP请求走私

    • OAuth身份验证漏洞

    • JWT攻击

    • 原型链污染

      • 原型链污染
      • JavaScript原型和继承
        • JavaScript原型和继承
        • JavaScript对象?
        • JavaScript原型?
        • 对象继承在JavaScript中是如何工作的?
        • 原型链
        • 使用_proto_访问对象的原型
        • 修改原型
      • 客户端原型链污染漏洞
      • 通过浏览器APIs实现客户端原型链污染
      • 服务端原型链污染漏洞
      • 防范原型链污染漏洞
    • 基本技能

  • 扩展阅读(翻译)

  • 个人学习笔记

  • 实验室做题记录

  • BurpSuite及官方实验室
  • 高级主题(翻译)
  • 原型链污染
carsaid
2024-02-20
目录

JavaScript原型和继承

翻译

原文:https://portswigger.net/web-security/prototype-pollution/javascript-prototypes-and-inheritance

- name: 翻译
  desc: 原文:https://portswigger.net/web-security/prototype-pollution/javascript-prototypes-and-inheritance
  bgColor: '#F0DFB1'
  textColor: 'green'
1
2
3
4

# 1JavaScript原型和继承

JavaScript 使用 “原型继承模型”,这与许多其他语言使用的 “基于类的模型” 完全不同。在本节中,我们将对其工作原理作一个基本的概述,这可以给予你足够的理解,从而更好地阅读我们关于原型链污染漏洞 (opens new window)的学习材料。

# 2JavaScript对象?

JavaScript 对象实际上只是一个被称为 “properties”(属性)的key:value对集合。例如,以下对象可以表示一个用户:

const user =  {
    username: "wiener",
    userId: 01234,
    isAdmin: false
}
1
2
3
4
5

你可以使用点表示法 或 括号表示法,来引用对象各自的键,从而访问对象的属性:

user.username     // "wiener"
user['userId']    // 01234
1
2

除数据外,属性也可以是一个可执行函数。在这种情况下,该函数被称为 “方法”。

const user =  {
    username: "wiener",
    userId: 01234,
    exampleMethod: function(){
        // do something
    }
}
1
2
3
4
5
6
7

上面的示例是一个 “对象字面量”,它是使用花括号语法来创建的,以显式声明其属性及其初始值。并且, JavaScript 中的几乎所有内容都是一个底层对象,这个理解很重要。在这些材料中,术语 “对象” 指的是所有实体,而不仅仅是对象字面量。

# 3JavaScript原型?

JavaScript 中的每个对象都会链接到某种类型的另一个对象,其被称为原型。默认情况下,JavaScript 会自动为新对象分配一个内置原型。例如,会为字符串对象自动分配内置的String.prototype。你可以在下面看到这些全局原型的更多示例:

let myObject = {};
Object.getPrototypeOf(myObject);    // Object.prototype

let myString = "";
Object.getPrototypeOf(myString);    // String.prototype

let myArray = [];
Object.getPrototypeOf(myArray);     // Array.prototype

let myNumber = 1;
Object.getPrototypeOf(myNumber);    // Number.prototype
1
2
3
4
5
6
7
8
9
10
11

对象会自动继承所分配原型的所有属性,除非该对象已经定义过了相同的键属性。这使得开发人员可以复用现有的对象属性和方法,基于现有的功能来创建一个新对象。

内置的原型提供了 用于处理基本数据类型的有用属性和方法。例如,String.prototype对象有一个toLowerCase()方法,因此,所有的字符串都会自动拥有一个 将自身转换为小写 的现成方法。这样一来,开发人员就不需要手动为每个新字符串添加该方法了。

# 4对象继承在JavaScript中是如何工作的?

每当你引用对象的属性时,JavaScript 引擎首先会尝试在对象自身上访问该属性,如果对象自身没有匹配的属性,则 JavaScript 引擎会在对象的原型上查找该属性。给定以下对象,这使你能够引用myObject.propertyA,例如:

Not Found Image

你可以使用 浏览器控制台 来查看此行为的实际效果。首先,创建一个空对象:

let myObject = {};
1

接下来,键入myObject和一个点号。请注意,控制台会提供一个属性和方法列表,供你从中进行选择:

Not Found Image

尽管你还没有为 对象本身 定义任何属性或方法,它也会从内置的Object.prototype上继承一些属性或方法。

# 5原型链

请注意,一个对象的原型 其实就是 另一个对象,而这个对象也应该有自己的原型,以此类推。实际上,JavaScript 中的几乎所有内容都是一个对象,最终,这条原型链会回到顶级的Object.prototype身上,其原型是一个null。

Not Found Image

至关重要的是,对象不仅会从它们的直接原型上继承属性,而且还会从原型链中的所有对象上继承属性。在上面的示例中,这意味着username对象可以访问String.prototype和Object.prototype上的属性和方法。

# 6使用__proto__访问对象的原型

每个对象都具有一个特殊的属性,你可以通过该属性来访问该对象的原型。虽然这个特殊属性还没有一个正式的标准化名称,但__proto__是大多数浏览器支持的事实标准。如果你熟悉面向对象的语言,则此属性既可以用作对象原型的 “getter”(获取值)又可以用作 “setter”(设置值)。这意味着,你可以使用它来读取原型及其属性,在必要时也可以进行重新设置。

与任何属性一样,你可以使用括号或点号表示法来访问__proto__:

username.__proto__
username['__proto__']
1
2

你甚至可以将__proto__的引用全部链接在一起,从而沿着原型链访问上一层级:

username.__proto__                        // String.prototype
username.__proto__.__proto__              // Object.prototype
username.__proto__.__proto__.__proto__    // null
1
2
3

# 7修改原型

虽然这通常被认为是不好的做法,但可以像修改任何其他对象一样修改 JavaScript 的内置原型。这意味着,开发人员可以自定义 或 覆盖内置方法的功能,甚至可以添加新方法来执行有用的操作。

例如,现代 JavaScript 为字符串提供了trim()方法,它使你能够轻松地删除任何前导或尾随空格。在官方引入这个内置方法之前,开发人员有时会执行以下操作,将此功能的自定义实现添加到String.prototype对象中:

String.prototype.removeWhitespace = function(){
    // remove leading and trailing whitespace
}
1
2
3

由于原型继承的存在,所有字符串都可以访问这个方法:

let searchTerm = "  example ";
searchTerm.removeWhitespace();    // "example"
1
2

接下来呢?

现在,你已经基本了解了 JavaScript 原型和继承的工作方式,让我们来看看其中的实现缺陷 是如何导致原型链污染漏洞的。

  • 什么是原型链污染? (opens new window)
编辑 (opens new window)
原型链污染
客户端原型链污染漏洞

← 原型链污染 客户端原型链污染漏洞→

最近更新
01
API测试笔记
04-30
02
msfvenom
03-29
03
Metasploit
03-29
更多文章>
Theme by Vdoing | Copyright © 2023-2024 Carsaid | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式