Десериализация на Java с предварителна проверка

Как да защитим непроверена десериализация на входа без криптиране и изолиране

Други клопки на десериализацията

Процесът на десериализация е подложен на още три опасности.

  • Нападателят може да "подслушва" съобщение и да прихваща чувствителни данни. Защита на транспортния слой (TLS) може да се използва за предотвратяване на този тип атака.
  • Атакуващият може да подправи данни, законно сериализирани от клиентското приложение и да наруши бизнес логиката на услугата. Както при другите услуги, проверката на входа трябва да се извършва на сървъра, дори ако същата проверка вече е извършена на клиента. Изолирането на обекти също може да бъде ефективно противодействие в този сценарий.
  • Нападателят може да установи частни членове на обект, които се държат по различен начин от намерението на разработчиците. По този начин нападателят може да промени вътрешното състояние на обект. Част от решението е да се маркират такива членове като преходни .

По-нататъшното обсъждане на тези въпроси и свързаните с тях противодействия е извън обхвата на тази статия.

Уязвими класове

Услугите не трябва да десериализират обекти от произволни класове. Защо? Кратък отговор: защото в пътя на класа на сървъра може да има уязвими класове, които нападателят може да използва. Тези класове могат да съдържат код, който ще доведе до отказ на услуга или, в краен случай, да смесва произволен код.

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

  • класът на злонамерения обект присъства в пътя на класа на сървъра. Нападателят не може просто да изпрати сериализиран обект от който и да е клас, защото услугата няма да може да зареди този клас;
  • класът на злонамерения обект - сериализуем или екстернализуем. (Тоест класът на сървъра трябва да реализира интерфейса java.io.Serializable или интерфейса java.io.Externalizable.)

Освен това процесът на десериализация попълва дървото на обекта, като копира данни от сериализирания поток, без да извиква конструктора. Следователно нападателят не би могъл да изпълни Java код в конструктора на сериализиращия се клас на обекта.

Но има и други начини за изпълнение на код на сървъра. JVM извиква метод и изпълнява кода вътре в него, когато десериализира обект от класа, който реализира един от следните три метода:

  • методът readObject (), често използван от разработчиците, когато не може да се приложи стандартна сериализация, например, ако трябва да зададете преходен член;
  • методът readResolve (), често използван за сериализиране на единични екземпляри;
  • метод readExternal (), използван за обекти, които могат да се екстернализират.

Така че, ако има класове в classpath, които използват някой от тези методи, имайте предвид, че нападателят може да извика тези методи дистанционно. По едно време този тип атака се използва за хакване на пясъчника на Applet (вж. Ресурси); същият метод може да се приложи срещу сървъра.