为什么调用带有变量的数组索引很糟糕?

Nev*_*ios 5 javascript arrays optimization codacy

我目前正在用Javascript开发一个小游戏,并且正在使用Codacy查看我的代码并帮助我清理它。

最常见的错误之一是通用对象注入接收器(安全性/检测对象注入)。

当我尝试使用变量访问数组中的值时,就会发生这种情况。像这个例子:

function getValString(value)
{
    var values = ["Mis&eacuterable", "Acceptable", "Excellente", "Divine"];
    return values[value];
}
Run Code Online (Sandbox Code Playgroud)

此功能用于在屏幕上显示项目的值字符串。它接收一个可以为0、1、2或3的“值”,并返回该值的字符串。

现在这是我的问题:

Codacy告诉我应该禁止使用var [var],因为它会引起安全问题,并且由于我对javascript不太熟悉,所以我想知道为什么以及在这种情况下的良好做法是什么?

con*_*ion 10

这里存在的安全问题是字符串化的值value可能正在访问从对象的__proto__分层原型继承的属性,而不是对象本身的实际属性。

例如,考虑以下情况 whenvalue是 的字符串文字"constructor"

const property = "constructor";
const object = [];
const value = object[property];
Run Code Online (Sandbox Code Playgroud)

value在这个上下文中的结果将解析为Array()函数——它作为对象原型的一部分被继承,而不是object变量的实际属性。此外,被访问的对象可能已经覆盖了任何默认的继承Object.prototype属性,这可能是出于恶意目的。


通过进行object.hasOwnProperty(property)条件检查以确保对象实际上具有此属性,可以部分防止此行为。例如:

const property = "constructor";
const object = [];
if (object.hasOwnProperty(property)) {
    const value = object[property];
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果我们怀疑被访问的对象可能是恶意的或重写了 hasOwnProperty 方法,则可能需要直接使用从原型继承的 Object hasOwnProperty:Object.prototype.hasOwnProperty.call(object, property)
当然,这假设我们Object.prototype尚未被篡改。

这不一定是全貌,但它确实证明了一个观点。


查看以下资源,其中更详细地阐述了为什么会出现此问题以及一些替代解决方案:


Laj*_*pad 6

就其本身而言,这并不是一个坏习惯,因为您确实想要开发一个系统并确保其安全。很难想象一个系统面临的安全风险比导致该系统不存在的风险还要高。

然而,不允许使用变量来动态创建/使用/更新索引实际上减少了对可能用于引用数组项或对象成员的任何索引进行硬编码的选择。

不允许索引会大大减少您的选择,以至于您可能想要用 Javascript 创建的任何系统都可能不存在。让我们看看一些用例:

编号循环:

for (let index = 0; index < arr.length; index++) {
    //do whatever with arr[index]
}
Run Code Online (Sandbox Code Playgroud)

当然,while循环也是如此。

循环中

for (let index in variable) {
    //do whatever with arr[index]
}
Run Code Online (Sandbox Code Playgroud)

循环数

for (let item of variable) {
    // do whatever with item
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

动态寻找一个值

这实际上有无数种用途,上面的所有例子都是这种情况的具体情况。例子:

function getItem(arr, index) {
    return arr[index];
}
Run Code Online (Sandbox Code Playgroud)

概括

由于动态索引而对漏洞利用的恐惧相当于一颗流星撞击到确切地点和确切时间的恐惧。当然,我们不能排除它,但一个人不能生活在对低概率的持续恐惧中灾难。同样,如果有不合理的、偏执的恐惧,编程也是不可能的。因此,我们不能因为存在漏洞而完全拒绝动态索引,而必须参考可能的实际漏洞。如果我们不允许使用动态实例,那么无论我们要开发什么系统,如果它不那么简单,都不会存在。因此,无论我们害怕什么威胁,都应该采取其他措施来防范。

示例:您从数据源检索值并有一个信用卡 IBAN 字段。是的,如果向非所有者的用户显示该信息,则风险很高。但您应该通过仅通过外部源(例如用户浏览器发送的 POST 请求)使用索引来使 IBAN 不可用来防止这种情况发生。