Как определить проблемы десериализации java?

Я хотел бы иметь возможность обнаружить проблемы с десериализацией в java-коде. Что мне искать? Например, как определить, пытается ли какой-то код java использовать "ошибка календаря java"? Обратите внимание, что я не программист java, но я понимаю концепции сериализации и ООП в порядке. Я пытаюсь реализовать некоторые проверки безопасности (что-то вроде инструмента предупреждения компилятора).

EDIT: на основе замечаний, я хотел бы изменить вопрос немного: Я считаю весь анализируемый код "ненадежным", есть ли способ оценить потенциальную опасность? Я имею в виду, могу ли я сказать, что код A более опасен, чем B в отношении ошибки десериализации? Что мне искать?

4 ответов


во-первых, вам нужно понять свой контекст, чтобы определить угрозы безопасности. (Когда я говорю о "доверии", Я беру небольшой короткий путь. Я говорю намеренно злонамеренно.)

если сериализованные данные были созданы, сохранены и прочитаны с тем же доверием, то нет никакой реальной проблемы (кроме стандартных ошибок). Примечание. Если вы пишете какую-либо конфиденциальную информацию, то сериализованные данные также являются конфиденциальными (это кажется очевидным, но есть изрядное количество косвенных).

если сериализованные данные ненадежны по какой-либо причине, то есть немного больше, чтобы рассмотреть. Внутренняя структура воссозданных объектов может быть "необычной". Данные могут быть несогласованными. Возможно, у вас есть общие изменяемые объекты, которые должны быть отдельными. Десериализация может привести к бесконечному циклу или не бесконечному циклу, который просто не может быть завершен до тепловой смерти Вселенной. И конечно, данные могут быть ложными.

если вы не написание кода библиотеки, который используется менее доверенным кодом, тогда все становится более интересным:

в случае "ошибки календаря" (и аналогичной) речь идет о десериализации произвольного потока с вредоносными данными и вредоносным кодом. Рекомендации по безопасному кодированию Java предлагают выполнять проверки безопасности (используя "модель безопасности Java2") в custom readObject методы, что означает, что вы не должны вызывать десериализацию с большим доверием, чем код и данные.

от с десериализуемыми объектами дела обстоят сложнее. Объекты, предоставляемые ObjectInputStream через readObject, readUnshared, defaultReadObject, readFields или только десериализация по умолчанию может иметь ссылки, захваченные вредоносным кодом или, для не-конечных классов, быть подклассом злонамеренно. Объект также может использоваться во время десериализации при частичной инициализации. Deserialisation не вызвать "реальный" конструктор класса deserialised (readObject/readObjectNoData является своего рода psuedo-конструктор, который не может установить finals). Это все немного кошмар, поэтому вы, вероятно, не хотите, чтобы ваши чувствительные классы сериализовались.

существует ряд уязвимостей при реализации сериализации и десериализации. Вам действительно не нужно беспокоиться об этом, если вы не реализуете его самостоятельно.


Мда... ваш вопрос немного общий. Вы взглянули на этой статьи? Речь идет об алгоритме сериализации Java, но из кэша Google, потому что главная страница, похоже, в данный момент не работает.


Я бы подумал, что лучший способ победить код, который использует известные дыры в безопасности в Java, - это перейти на версию Java, которая исправляет ошибку. И следующий лучший способ (для борьбы с ошибками, связанными с сериализацией) - рассматривать все сериализованные данные из неизвестных / непроверенных / небезопасных источников как подозрительные.

попытка определить проблемы путем анализа кода java для ошибок безопасности не проста и требует глубокого понимания механизмов Java, которые используются и могут быть эксплуатируемый. Попытка обнаружить попытки эксплойтов (в целом) будет еще сложнее, особенно если вы ищете эксплойты для дыр в безопасности нулевого дня. Имейте в виду, что существуют и другие потенциальные векторы.

(Если бы были простые способы найти неизвестные дыры безопасности в Java, вы можете поспорить, что Sun и другие исследователи безопасности уже использовали бы их.)


Если вы сериализуете свой объект Java для передачи его в отдельное приложение, почему бы не рассмотреть возможность подписания объекта с ключом, разделяемым между приложениями? Этого должно быть достаточно, чтобы защитить себя от нападения человека-в-середине.

возвращаясь к сути проблемы проверки, проверка чрезвычайно сложна для языков общего назначения. Вам стоит поискать научные публикации на эту тему. Я думаю, что наиболее часто применяемая техника изолирование. Второй подход состоит в том, чтобы ограничить язык и запретить выполнение опасных команд, например,библиотека Yahoo Caja использует эту технику.