💻 Ruby:
• Аналогично JS и Python, опасен рекурсивный
deep_merge или любое слияние, которое устанавливает инстанс- или класс-переменные на основе данных пользователя.• Не доверяйте
deep_merge на объектах: стандартный Hash#deep_merge безопасен для чистых хешей, но при объединении атрибутов объекта он может добавить методы. Всегда контролируйте, какие атрибуты ставятся через attr_accessor или instance_variable_set. Если используется ActiveSupport или Hashie для слияния, проверяйте, закрыты ли методы (Hashie блокирует переопределение методов, но ключи вида _/! могут обойти защиту).• Не используйте
eval/instance_eval или небезопасный to_proc на пользовательских данных.• Ограничивайте область действия включаемых модулей: при
include/extend убеждайтесь, что приватность методов не «размывается» — по возможности убирайте ненужные методы через undef_method или делайте их private. Это не устранит атаку слияния, но уменьшит «плохой» код, который можно подменить.• Замораживайте, по мере возможности: Ruby позволяет вызывать
freeze на объектах, исключая дальнейшее изменение их переменных. Подумайте о замораживании всех неизменяемых конфигурационных объектов, если это не сломает логику приложения.🖥 PHP:
• Прямого аналога прототипов тоже нет, но есть опасность перезаписи свойств: функции-слияния с объектов не имеют смысла (результат –
stdClass), однако стандартные foreach или (object)$array могут изменить экземпляр класса. Избегайте кода вида foreach($data as $k=>$v) { $obj->$k = $v; } без фильтрации ключей.• Используйте массивы вместо объектов: например, при
json_decode($json) указывайте вторым параметром true, чтобы получить массив, а не объект. Тогда не получится неявно «пролить» данные в объект.• Проверяйте ключи и поля: если какие-то поля приходят из запроса и затем ставятся в атрибуты объектов — убедитесь, что это ожидаемые поля. Незнакомые ключи — игнорируйте или блокируйте.
• Не используйте
unserialize() на пользовательских данных: это другая категория уязвимостей, но тоже позволяет менять внутренние данные объектов. Для передачи сложных структур лучше json_encode/decode с валидацией.Другие языки:
• В💻 Java и 💻 необходимо следить за безопасностью десериализации и рефлексии (в том числе — неявной, на стороне используемого фреймворка). Например, не внедрять из JSON имена классов/методов напрямую (
Class.forName и т.п.); в конфигурационных классах делать поля private final. Используйте sealed или final классы везде, где это возможно. В 👣 и 👣 Rust аналогичная история: в общем подходе по-прежнему нужно валидировать JSON по структуре (Go) и использовать serde/serde_json (Rust) без включения нестандартных поведений.Как-то так 🤓
⚠ TL;DR:
Лонгрид — не заслуживает внимания, оставайтесь c уязвимыми проектами)
#уязвимости