Вопрос или проблема
Во многих руководствах по загрязнению прототипов функции “слияния” рассматриваются как потенциально уязвимые. Но я несколько запутался, как это должно работать, если функция слияния не рекурсивная. Например, в этом руководстве приводится уязвимая функция, подобная следующей:
function merge(target, source) {
var output = JSON.parse(target);
for (var key in source) {
output[key] = source[key];
}
return output;
}
Однако я не понимаю, как это может быть уязвимо.
Давайте немного упростим:
const output = {}
output[attackerControlledKey] = attackerControlledValue
Я не могу найти полезную нагрузку, которая действительно могла бы модифицировать прототип. __proto__.isAdmin
в качестве attackerControlledKey
не работает, насколько я вижу.
Если бы это было так:
const output = {}
output[attackerControlledFirstKey][attackerControlledSecondKey] = attackerControlledValue
то, конечно, злоумышленник мог бы установить __proto__
в качестве attackerControlledFirstKey
и общепринятое значение isAdmin
в качестве attackerControlledSecondKey
, а true
в качестве attackerControlledValue
Я понимаю, что многие из таких функций слияния на самом деле рекурсивные, как пример, приведенный здесь.
Но я думаю, если злоумышленник может установить только один ключ и значение, не имея возможности углубляться, тогда проблем нет. Это правильно? Или я что-то упускаю?
Ответ или решение
Проблема Полиции Прототипов в Нерекурсивной Функции Слияния
В современном мире разработки программного обеспечения, безопасность остается приоритетной задачей, и одна из уязвимостей, на которую стоит обратить внимание, — это полицией прототипов. Эта уязвимость может возникать в различных контекстах, включая функции слияния. Однако аргумент о том, что нерекурсивные функции слияния не подвержены этой уязвимости, требует более глубокого анализа.
Основные Принципы Прототипной Полиции
Прототипная полиция (Prototype Pollution) относится к возможности изменения или добавления свойств к прототипу объектов с помощью злоумышленника. Это происходит, когда данные, предоставленные пользователем, неправомерно обрабатываются и сохраняются в прототипах объектов, тем самым влияя на все экземпляры этих объектов.
Анализ Нерекурсивной Функции Слияния
Рассмотрим предложенный фрагмент кода:
function merge(target, source) {
var output = JSON.parse(target);
for (var key in source) {
output[key] = source[key];
}
return output;
}
На первый взгляд, в этой функции не видно очевидной уязвимости к атаке через прототип. В частности, если мы посмотрим на так называемую «атакующую нагрузку», например, назначаемое значение __proto__.isAdmin
в качестве attackerControlledKey
, кажется, что это не сработает, поскольку слияние, по всей вероятности, добавит значение isAdmin
в объект output
, а не изменит его на прототипе объекта Object
.
Почему Это Мнение Может Быть Ложным
-
Указание на Прототип Непосредственно: Если в качестве ключа используется
__proto__
, это может напрямую изменять поведениеObject.prototype
, посколькуoutput
– это объект, который может вести себя как любой другой в JavaScript. Таким образом, еслиattackerControlledKey
будет__proto__
, аattackerControlledValue
— некий объект, это может привести к неожиданным последствиям. -
Изменение Других Прототипов: Если целевой объект(
target
) является объектом, который наследует от другого объекта, использование данного кода может привести к нарушению целостности за счет добавления свойств, которые могут быть затем использованы для обхода аутентификации или авторизации. -
Необходимость Обработки На Уровне Модулей: В ситуациях, когда слияние происходит не только на уровне одного объекта, а и касается более сложной структуры данных, это может вызвать еще более серьезные последствия.
Заключение
В рамках данного анализа можно утверждать, что, хотя на первый взгляд нерекурсивная функция слияния может не представлять собой явную уязвимость к прототипной полиции, потенциальные риски все же существуют. Злоумышленник может воспользоваться тем фактом, что функции слияния могут использовать __proto__
или другие ключевые слова для изменения поведения прототипов объектов.
Предотвращение таких уязвимостей требует внимательного контроля над входными данными и осознания того, как JavaScript обрабатывает объекты и их прототипы. При разработке любых функций слияния важно учитывать эти факторы, что послужит надежным барьером к потенциальным атакам и повысит общую безопасность программного обеспечения.