关于javascript解决闭包漏洞的一个问题详解

目录
  • 解决闭包漏洞的一个问题
  • 问题原理:
  • 方法一:
  • 方法二:
  • 解决办法;
  • 解决方法二:
  • 总结

解决闭包漏洞的一个问题

在不修改下面代码的情况下,修改obj的内容

var o = (()=>{
    var obj = {
        a:1,
        b:2,
    };
    return {
        get :(n)=>{
            return obj[n]
        }
    }
})()

上面代码就是一个典型的闭包模式。屏蔽掉obj本身。只能访问闭包返回的数据而不能去修改数据源本身,但是他的数据源是一个对象,这就会出现一个漏洞!!!!,而上面的代码就会出现一个致命的漏洞。

问题原理:

console.log(o.get("a"));//1
console.log(o.get("b"));//2

貌似我们在没有可选值传入了?但是你要记住,在js中万物皆是对象,对象通过原型来继承原型对象上的属性和方法。

Object.protoType()原型对象。

方法一:

那我能不能去访问到原型valueOf,暂时说想通过valueOf()来获取这个对象本身。

JavaScript 中的 valueOf() 方法用于返回指定对象的原始值,若对象没有原始值,则将返回对象本身。

console.log(o.get("valueOf"));
//[Function: valueOf]
let obj2 = o.get("valueOf")()
//TypeError: Cannot convert undefined or null to object

可以看的出来,报错,这是因为valueOf函数的this指向发生了错误

方法二:

  • 虽然提供了一个函数进入传参,但是传入的权限很大,就会有很大的问题。
  • 有没有一种方法,直接访问对象的属性的时候通过一个函数来获取,这时候就是构造器属性。
  • 给对象的原型设置一个访问器属性
Object.defineProperty(Object.prototype,"abc",{
    get(){
        return this
    }
})
console.log(o.get("abc"));//{ a: 1, b: 2 }

在这里就会通过访问这个原型链上的访问器属性来返回一个访问它这个的对象,这样我就拿到了这个对象。

let obj = o.get("abc")
obj.a='hjkasd'
obj.b='12345'
obj.c='勇敢牛牛,不怕困难'
console.log(obj);//{ a: 'hjkasd', b: '12345', c: '勇敢牛牛,不怕困难' }

这就导致一个很严重的问题。我能修改 闭包的值。如果是第三方库。那很轻易的破坏了库的结构。

解决办法;

我刚才通过访问原型链上的属性,达到返回这个寻求的对象。从而破会掉结构。

那么就需要判断访问的属性是否来自对象本身。从而返回不同的值。

var o = (()=>{
    var obj = {
        a:1,
        b:2,
    };
    return {
        get :(n)=>{
            if(!obj.hasOwnProperty(n)){
                return `${n}在此对象本身不存在`
            }
            return obj[n]
        }
    }
})()

解决方法二:

直接设置这个对象的原型为null,没有原型链,那我上面的逻辑就行不通,自然就保护了数据的隐私性。

var o = (()=>{
    let obj = {
        a:1,
        b:2,
    };
    Object.setPrototypeOf(obj,null)
    return {
        get :(n)=>{
            return obj[n]
        }
    }
})()

总结

到此这篇关于javascript解决闭包漏洞的一个问题的文章就介绍到这了,更多相关js解决闭包漏洞内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2022-11-02

Javascript的作用域、作用域链以及闭包详解

一.javascript中的作用域 ①全局变量-函数体外部进行声明 ②局部变量-函数体内部进行声明 1)函数级作用域 javascript语言中局部变量不同于C#.Java等高级语言,在这些高级语言内部,采用的块级作用域中会声明新的变量,这些变量不会影响到外部作用域. 而javascript则采用的是函数级作用域,也就是说js创建作用域的单位是函数. 例如: 在C#当中我们写如下代码: static void Main(string[] args) { for (var x = 1; x < 1

JavaScript 中的作用域与闭包

目录 一.JavaScript 是一门编译语言 1.1 传统编译语言的编译步骤 1.2 JavaScript 与传统编译语言的区别 二.作用域(Scope) 2.1 LHS查询 和 RHS查询 2.2 作用域嵌套 2.3 ReferenceError 和 TypeError (1)ReferenceError (2)TypeError (3)ReferenceError 和 TypeError 的区别 小结 三.词法作用域 3.1 词法阶段 3.2 词法作用域 查找规则 3.3 欺骗词法 ——

JavaScript三大重点同步异步与作用域和闭包及原型和原型链详解

目录 1. 同步.异步 2. 作用域.闭包 闭包 作用域 3. 原型.原型链 原型(prototype) 原型链 如图所示,JS的三座大山: 同步.异步 作用域.闭包 原型.原型链 1. 同步.异步 JavaScript执行机制,重点有两点: JavaScript是一门单线程语言 Event Loop(事件循环)是JavaScript的执行机制 JS为什么是单线程 最初设计JS是用来在浏览器验证表单操控DOM元素的是一门脚本语言,如果js是多线程的,那么两个线程同时对一个DOM元素进行了相互冲突

一文详解JavaScript闭包典型应用

目录 1.应用 1.1 模拟私有变量 1.2 柯里化 1.3 偏函数 1.4 防抖 1.5 节流 2.性能问题 2.1 内存泄漏 2.2 常见的内存泄漏 3.闭包与循环体 3.1 这段代码输出啥 3.2 改造方法 4.总结 1.应用 以下这几个方面是我们开发中最为常用到的,同时也是面试中回答比较稳的几个方面. 1.1 模拟私有变量 我们都知道JS是基于对象的语言,JS强调的是对象,而非类的概念,在ES6中,可以通过class关键字模拟类,生成对象实例. 通过class模拟出来的类,仍然无法实现传

一文剖析JavaScript中闭包的难点

目录 一.作用域基本介绍 1. 全局作用域 2. 函数作用域 3. 块级作用域 二.什么是闭包 1. 闭包的基本概念 2. 闭包产生的原因 3. 闭包的表现形式 三.如何解决循环输出问题 1. 利用 IIFE 2. 使用 ES6 中的 let 3. 定时器传入第三个参数 一.作用域基本介绍 ES6之前只有全局作用域与函数作用域两种,ES6出现之后,新增了块级作用域. 1. 全局作用域 在JavaScript中,全局变量是挂载在window对象下的变量,所以在网页中的任何位置你都可以使用并且访问到

深入剖析JavaScript中的函数currying柯里化

curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字命名).   柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果. 因此柯里化的过程是逐步传参,逐步缩小函数的适用范围,逐步求解的过程. 柯里化一个求和函数 按照分步求值,我们看一个简单的例子 var concat3Words = function (a, b, c) { r

javascript中闭包概念与用法深入理解

本文实例分析了javascript中闭包概念与用法.分享给大家供大家参考,具体如下: 1.问题的引出,什么时候会遇到闭包? 首先因为JS是没有块状作用域的,但是有函数作用域即函数作为了局部变量之间的界限,不同函数内的局部变量具有独立性, 因为JS没有块状作用域,笔者初学JS时,在事件的监听时,因为不理解JS中局部变量的作用域,犯过不少错误! (1)JS中的变量作用域 for(var i=0;i<9;i++) { } alert(i) //输出9 我们发现,虽然变量i是块状区域for()内的一个局

JavaScript中闭包之浅析解读(必看篇)

JavaScript中的闭包真心是一个老生常谈的问题了,最近面试也是一直问到,我自己的表述能力又不能完全支撑起来,真是抓狂.在回来的路上,我突然想到了一个很简单的事情,其实我们在做项目时候,其实就经常用到闭包的,可是面试问的时候,回答又往往是我们经常搜到的答案,唉 不管是应付面试 还是真的想学点东西 ,我也用自己的理解跟大家分享一下,书面化就避免不了了的. 1.闭包是什么? 红宝书中曰:"是指有权访问另外一个函数作用域中的变量的函数." 简单的说,JavaScript允许使用内部函数-

JavaScript中闭包的写法和作用详解

1.什么是闭包 闭包是有权访问另一个函数作用域的变量的函数. 简单的说,Javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内.而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数和声明的其他内部函数.当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包. 2.变量的作用域 要理解闭包,首先要理解变量的作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变

深入剖析javascript中的exec与match方法

exec是正则表达式的方法,而不是字符串的方法,它的参数才是字符串,如下所示: var re=new RegExp(/\d/); re.exec( "abc4def" ); //或者使用perl风格: /\d/.exec( "abc4def" ); //match才是字符串类提供的方法,它的参数是正则表达式对象,如下用法是正确的: "abc4def".match(\d); exec和match返回的都是数组 如果执行exec方法的正则表达式没有分

JavaScript中闭包的详解

闭包是什么 在 JavaScript 中,闭包是一个让人很难弄懂的概念.ECMAScript 中给闭包的定义是:闭包,指的是词法表示包括不被计算的变量的函数,也就是说,函数可以使用函数之外定义的变量. 是不是看完这个定义感觉更加懵逼了?别急,我们来分析一下. 闭包是一个函数 闭包可以使用在它外面定义的变量 闭包存在定义该变量的作用域中 好像有点清晰了,但是使用在它外面定义的变量是什么意思,我们先来看看变量作用域. 变量作用域 变量可分为全局变量和局部变量.全局变量的作用域就是全局性的,在 js

javascript中闭包(Closure)详解

在javascript中,函数可看作是一种数据,可以赋值给变量,可以嵌套在另一个函数中. var fun = function(){ console.log("平底斜"); } function fun(){ var n=10; function son(){ n++; } son(); console.log(n); } fun(); //11 fun(); //11 我们把上面第二段代码稍微修改下: var n=10; function fun(){ function son(){

深入剖析JavaScript中的枚举功能

由于 Microsoft AJAX Library 对于 JavaScript 进行了大幅扩展, 枚举这个常用的功能当然也被加进去了, 本次就是来探讨 JavaScript 的枚举功能. 由于范例很简单, 所以直接看 HTML 标签就 OK 了 复制代码 代码如下: <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">     <title></t

Javascript中return的使用与闭包详解

前言 Javascript中闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.而return语句在js中起到举足轻重的作用,该关键字不仅具有返回函数值得功能,还具有一些特殊的用法,下面就来看看关于Javascript中return的使用与闭包的详细介绍吧. 一.return的使用 案例一: var a=1; for(var b=0; b<10; b++){ return b; }; sonsole.log(b)//返回为空 个人认为此处左右

javascript的闭包介绍(司徒正美)

闭包的定义非常晦涩--闭包,是指语法域位于某个特定的区域,具有持续参照(读写)位于该区域内自身范围之外的执行域上的非持久型变量值能力的段落.这些外部执行域的非持久型变量神奇地保留它们在闭包最初定义(或创建)时的值(深连结).简单来说,闭包就是在另一个作用域中保存了一份它从上一级函数或作用域取得的变量(键值对),而这些键值对是不会随上一级函数的执行完成而销毁.周爱民说得更清楚,闭包就是"属性表",闭包就是一个数据块,闭包就是一个存放着"Name=Value"的对照表.