Найдите уязвимость в этом Java-фрагменте: ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); Object obj = in.readObject(); — какие риски несёт десериализация стороннего ввода и как их уменьшить?

3 Дек 2025 в 13:56
31 +2
0
Ответы
1
Коротко — уязвимость: десериализация данных от незнакомого/внешнего источника даёт возможность атакующему выполнить произвольный код, вызвать DoS или получить/подменить данные в приложении (через т.н. gadget‑цепочки и поведение методов readObject()/readResolve()).
Основные риски
- Удалённое выполнение кода (RCE) через gadget‑цепочки (например, известные уязвимости в commons‑collections, spring и т.п.).
- Отказ в обслуживании: большое/рекурсивное/злонамеренно сконструированное дерево объектов → OOM/CPU.
- Информационное раскрытие: десериализация внутренних типов даёт доступ к чувствительным полям.
- Подмена/повреждение данных, обход авторизации.
- Зависимость от классов в classpath — загрузка неожиданных типов.
Как уменьшить риск (рекомендации)
1. По возможности не использовать Java‑сериализацию для внешнего ввода: заменить на безопасные форматы (JSON, protobuf, CBOR) с явной схемой и валидацией.
2. Использовать фильтрацию типов (allowlist) при десериализации: ObjectInputFilter (в Java 9+Java\ 9+Java 9+) или setObjectInputFilter. Пример:
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(
"com.myapp.Safe*;java.lang.String;java.lang.Integer;!*"
);
in.setObjectInputFilter(filter);
Object obj = in.readObject();
Это позволяет отклонять любые типы, не в списке разрешённых.
3. Ограничивать ресурсы: максимальная глубина объектов, максимальное количество элементов, общий размер — через фильтр или проверкой после разбора.
4. Подписывать/шифровать поток сериализованных данных: отправитель подписывает байты (MAC/PKI), получатель проверяет подпись перед десериализацией — защита от подделки.
5. Валидировать объекты после десериализации: проверять поля и состояния, не доверять сразу.
6. Песочница/изолированный процесс: выполнять десериализацию в отдельном JVM/контейнере с минимальными правами и ограничением памяти/CPU; при обнаружении аномалий — убивать процесс.
7. Обновлять JRE и библиотеки (патчи против известных gadget‑уязвимостей).
8. При невозможности перейти от сериализации — использовать строгую программную проверку входящих классов (ручной allowlist) и избегать readObject в нестабильных типах.
Короткий чек‑лист для внедрения
- Отказаться от Java‑сериализации для внешних данных, если можно.
- Если нет — применять ObjectInputFilter с allowlist.
- Подписывать/шифровать данные.
- Ограничивать ресурсы и запускать в изолированном окружении.
- Логировать и обновлять зависимости.
Если нужно — могу привести конкретный пример ObjectInputFilter‑реализации или показать схему подписи/проверки для вашего протокола.
3 Дек 2025 в 14:05
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир