Почему это плохая практика, вызывающая индекс массива с переменной?

В настоящее время я разрабатываю небольшую игру на Javascript и использую Codacy для проверки своего кода и помощи в его очистке. .

Одной из наиболее часто встречающихся ошибок является Generic Object Injection Sink (security/detect-object-injection).

Это происходит, когда я пытаюсь получить доступ к значению в массиве с помощью переменной. Как в этом примере:

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

Этот function используется для отображения на экране строки значения элемента. Он получает значение, которое может быть 0, 1, 2 или 3, и возвращает строку значения.

Теперь вот моя проблема:

Codacy говорит мне, что использование var[var] должно быть запрещено, потому что это вызывает проблемы с безопасностью, и, поскольку я новичок в Javascript, мне было интересно, почему и каковы хорошие практики в такой ситуации.


person Nevios    schedule 03.07.2017    source источник
comment
Код выглядит нормально. Однако здесь более уместным будет переключатель или таблица поиска...   -  person Jonas Wilms    schedule 03.07.2017
comment
Нет, просто карта значения:коэффициент. И однострочный...   -  person Lazyexpert    schedule 03.07.2017
comment
Оба не отвечают на вопрос ОП - почему поиск индекса массива считается плохой практикой безопасности и действительно ли это?   -  person shotor    schedule 03.07.2017
comment
Мне кажется, потому что поиск зависит от параметра внешней функции, которым теоретически могут манипулировать клиенты, которые сами по себе МОГУТ вызывать какие-либо плохие вещи, такие как переполнение буфера или что-то еще, что может быть использовано. Разве не существует часть документации по кодированию, объясняющая эту проблему?   -  person Jankapunkt    schedule 03.07.2017
comment
Да, вы правы, в документации указано, что это может привести к множеству эксплойтов. Я думаю, мне придется исправить это везде: с   -  person Nevios    schedule 03.07.2017
comment
Я думаю, что Codacy должен улучшить проверки, потому что эта операция является плохой практикой безопасности только тогда, когда переменная, используемая в качестве индекса, получена извне (например, пользовательский ввод или аргумент), а не когда это локальная переменная (например, для/пока счетчик циклов).   -  person Fabio Caccamo    schedule 19.11.2019


Ответы (2)


Присутствующая здесь проблема безопасности заключается в том, что строковое значение 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 еще не был подделан. с.

Это не обязательно полная картина, но она демонстрирует суть.


Ознакомьтесь со следующими ресурсами, в которых более подробно объясняется, почему возникает эта проблема, и некоторые альтернативные решения:

person concision    schedule 05.10.2020

Само по себе это неплохая практика, потому что вы действительно хотите разработать систему и сделать ее безопасной. Трудно представить более высокий риск безопасности для системы, чем тот, который вызывает несуществование этой системы.

Тем не менее, запрет на использование переменной для динамического создания/использования/обновления индекса практически сужает ваши возможности жесткого кодирования любых индексов, которые вы можете использовать для ссылки на элементы массива или элементы объекта.

Отказ от индексов сильно ограничивает ваши возможности, настолько, что это грозит исчезновением любой системы, которую вы захотите создать на 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 кредитной карты. Да, если это показано пользователю, который не является владельцем, это высокий риск. Но вы должны защититься от этого, сделав IBAN недоступным, просто используя индекс из внешних источников, таких как POST-запросы, отправленные браузером пользователя.

person Lajos Arpad    schedule 05.10.2020