Десериализация — преобразование сохранённых или переданных данных обратно в программные объекты; если она применяется к недоверенным данным, атакующий может добиться выполнения кода.
Как работают атаки на десериализацию
Приложения сериализуют объекты — превращают их в байты, JSON или XML — чтобы сохранить или передать по сети, а на другой стороне десериализуют. Форматы вроде Java-сериализации, .NET BinaryFormatter, функции unserialize() в PHP или модуля pickle в Python умеют воссоздавать объекты произвольных типов и автоматически вызывать их методы. Атакующий, управляющий сериализованными данными, выстраивает из классов в библиотеках приложения «цепочки гаджетов» (gadget chains), так что при воссоздании объектов выполняются команды. Инструменты вроде ysoserial генерируют такие нагрузки автоматически.
Слабость описана как CWE-502. Исследование 2015 года о цепочках гаджетов в библиотеке Apache Commons Collections показало, что так можно атаковать множество Java-приложений, включая Jenkins и Oracle WebLogic.
Почему это важно
Небезопасная десериализация обычно ведёт к удалённому выполнению кода, часто без аутентификации, поэтому такие уязвимости получают высшие оценки опасности. Корпоративное промежуточное ПО, VPN-шлюзы и системы передачи файлов не раз взламывали через ошибки десериализации, а публичные эксплойты появляются быстро. Это близкий родственник внедрения кода, входящий в категорию OWASP Top 10 «Нарушения целостности ПО и данных».
Как предотвратить
- Не десериализовать данные из недоверенных источников с помощью нативных форматов объектов; использовать простые форматы вроде JSON со строгой схемой.
- Если без нативной десериализации не обойтись — применять белые списки допустимых классов и проверку целостности (подписи).
- Удалять неиспользуемые библиотеки, дающие цепочки гаджетов, и обновлять фреймворки.
- Отслеживать исключения десериализации и необычные дочерние процессы.