15

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

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

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

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

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

现在这是我的问题:

Codacy 告诉我var[var]应该禁止使用,因为它会导致安全问题,而且由于我对 Javascript 还比较陌生,所以我想知道为什么以及在这种情况下有哪些好的做法。

4

2 回答 2

12

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

例如,考虑当value是 的字符串文字时的场景"constructor"

const property = "constructor";
const object = [];
const value = object[property];

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


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

const property = "constructor";
const object = [];
if (object.hasOwnProperty(property)) {
    const value = object[property];
}

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

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


查看以下资源,这些资源更详细地说明了为什么这是一个问题以及一些替代解决方案:

于 2020-10-05T11:15:09.887 回答
0

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

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

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

编号循环:

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

当然,while循环也是如此。

在循环中

for (let index in variable) {
    //do whatever with arr[index]
}

循环数

for (let item of variable) {
    // do whatever with item
}

在此处输入图像描述

动态查找值

这实际上以准无限多种方式使用,以上所有示例都是这种情况的具体情况。例子:

function getItem(arr, index) {
    return arr[index];
}

概括

由于动态索引而对漏洞利用的恐惧,就相当于对流星击中确切位置和确切时间的恐惧。当然,我们不能排除它,但不能一直生活在对低概率的恐惧中灾难。同样,编程也是不可能的,带着不合理的、偏执的恐惧。因此,与其因为存在漏洞利用的可能性而完全拒绝动态索引,我们必须参考可能的实际漏洞利用。如果不允许我们使用动态实例,那么无论我们要开发什么系统,如果它不是那么简单,就不会存在。因此,我们害怕的任何威胁都应该受到保护。

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

于 2020-10-05T11:32:10.617 回答