Как определить проблемы десериализации Java? - PullRequest
7 голосов
/ 01 ноября 2010

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

РЕДАКТИРОВАТЬ: на основе комментариев я хотел бы немного изменить вопрос: я рассматриваю весь кодпроанализированы "недоверенные", есть ли способ, как оценить потенциальную опасность?Я имею в виду, могу ли я сказать, что код A более опасен, чем B, в отношении ошибки десериализации?Что я должен искать?

Ответы [ 4 ]

5 голосов
/ 01 ноября 2010

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

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

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

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

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

Со стороны десериализуемых объектов все сложнее. Объекты, предоставляемые с ObjectInputStream по readObject, readUnshared, defaultReadObject, readFields или просто десериализацией по умолчанию, могут иметь ссылки, захваченные вредоносным кодом, или, для неконечных классов, быть злонамеренно разделенными на подклассы. Объект может также использоваться во время десериализации при частичной инициализации. Десериализация не вызывает «реального» конструктора десериализованного класса (readObject / readObjectNoData является разновидностью псевдо-конструктора, который не может установить final s). Это всего лишь кошмар, так что вы, вероятно, не хотите, чтобы ваши чувствительные классы были сериализуемыми.

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

2 голосов
/ 01 ноября 2010

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

1 голос
/ 01 ноября 2010

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

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

1 голос
/ 01 ноября 2010

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

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

...