为什么用变量调用数组索引是不好的做法?

时间:2017-07-03 09:51:57

标签: javascript arrays optimization codacy

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

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

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

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

此功能用于在屏幕上显示项目的值字符串。它收到一个"值"可以是0,1,2或3,并返回值的字符串。

现在我的问题出现了:

Codacy告诉我应该禁止使用var [var],因为它会导致安全问题,而且因为我对javascript很新,我想知道为什么以及在这种情况下有什么好的做法。

3 个答案:

答案 0 :(得分:4)

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

例如,考虑当value"constructor"的字符串文字时的情况。

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

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


可以通过进行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尚未被篡改。

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


请查看以下资源,其中详细说明了这是一个问题的原因以及一些替代解决方案:

答案 1 :(得分:0)

通过索引访问有什么不好:该索引可能没有元素。

关于你的代码,我会制作一个预设地图:

const preset = {
  0: 0.5,
  1: 1.5,
  2: 2,
  3: 3
};

然后在功能中使用它:

function sellPotato(x, player) {
  // This additional check gives you more confidence in accessing element of and array by index
  if (player.inventory.length < x) return;

  if (preset[player.inventory[x].value]) {
    player.money += player.inventory[x].price * preset[player.inventory[x].value];
  }
  player.inventory.splice(x, 1);
  display(player);
}

答案 2 :(得分: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
}

请参阅enter image description here

动态查找值

实际上,它几乎可以以多种方式使用,上面的所有示例都是这种情况的特定情况。示例:

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

摘要

由于动态索引而对漏洞利用的恐惧等同于流星击中确切位置和确切时间的恐惧。当然,我们不能排除它,但不能生活在对恐惧的持续恐惧中低度灾难。同样,由于不合理,偏执的恐惧,编程也是不可能的。因此,我们必须参考可能的实际利用方式,而不是因为利用利用可能性而完全拒绝动态索引。如果不允许我们使用动态实例,那么我们要开发的任何系统(如果不是像馅饼一样简单)都将不复存在。因此,无论我们担心什么威胁,都应加以防范。

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