Инъекция вредоносного объекта с помощью xstream - PullRequest
1 голос
/ 31 мая 2011

Могу ли я безопасно использовать XStream для обработки XML, поступающего извне моей системы? Какова лучшая практика при работе с «потенциально вредоносным XML» с использованием xstream?

Скажем, у меня в коде есть класс, подобный этому:

 package hazard;
 class Dangerous {
    public Dangerous() {
       AtomicBomb.getInstance().nuke();
    }
 }

Злоумышленник может отправить файл XML, например:

 <hazard.Dangerous/>

и make XStream вызывает метод nuke ().

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

Дело в том, что отправка файла XML позволяет злоумышленнику создавать произвольные объекты. Более реалистичным подходом может быть использование одного класса вместо другого.

public class Foo<T implements Bar> {
    private T t;
    // Getters/setters ...
}

public interface Bar {
   public void bar();
}

public class Bar1 implements Bar {
   // ...
}

public class Bar2 implements Bar {
   // ...
}

С (вредоносным) вводом XML:

<foo>
  <!-- I expect bar1 -->
  <package.Bar2/>
</foo>

Теперь с кодом Java:

Bar<Foo1> bar = (Bar<Foo1>) xstream.fromXML(xml);
// I expect to have a bar1 but I have a bar2.
bar.getT().foo();

На первый взгляд, решение состоит в том, чтобы предоставить пользовательский Mapper (работа выполняется в методе realClass ()).

Ответы [ 2 ]

4 голосов
/ 31 мая 2011

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

ОБНОВЛЕНИЕ: Ваша упомянутая теория об использовании Mapper должна работать, хотя для этого потребуетсянекоторое количество лесов и пользовательских конфигураций, создаваемых вами.Другой способ - использовать функцию XStream для указания выделенного загрузчика классов для разрешения классов.То, что вы пытаетесь сделать, - это поместить все классы, которые СЛЕДУЕТ разрешить маршалировать с помощью xstream, в отдельный JAR-файл (думать о нем как о модуле домена).Затем создайте чистый загрузчик классов, который загружает только этот JAR-файл, и назначьте его в xstream.Таким образом, xstream не будет знать ни о каких классах за пределами своей области, не сможет десериализовать то, что вам не нужно.

Попробуйте что-то вроде

ClassLoader bootstrapClassLoader = ClassLoader.getSystemClassLoader().getParent();
List urls = new ArrayList();
urls.add(new File("yourJarOfXstreamBeanClasses.jar").toURL());
ClassLoader xstreamClassLoader = new URLClassLoader(urls.toArray(new URL[0]), bootstrapClassLoader);
XStream xstream = new XStream();
xstream.setClassLoader(xstreamClassLoader);
0 голосов
/ 31 мая 2011

Что если кто-то из вашей команды разработчиков позвонит DangerousClass()?XStream собирается сохранить объект, если вы читаете это, а XML изменился, вы в лучшем случае получите ClassCastException.

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

Если вы правильно кодируете, не должно быть никаких угроз безопасности, связанных с XStream.

...