com.thoughtworks.xstream.security.ForbiddenClassException

Я столкнулся с этим исключением при обновлении xstream (1.4.8) lib до последней версии в одном из наших веб-приложений. Исключение было брошено в pojo из зависимого jar, который был скомпилирован с использованием более старой версии xstream (1.3.1). Я перекомпилировал и собрал новый jar (зависимый jar) с использованием xstream-1.4.8 и снова развернул файл war, но все равно получил то же исключение. Изначально я думал, что это из-за несоответствия версий, сейчас я не уверен, что вызвало это исключение, и в Интернете не так много документации. Какие-нибудь мысли?

Спасибо, Картик

Фактический вызов, который выбрасывает исключение:

TestList list = (TestList)xs.fromXML(new StringReader(testData));

где testData - это строка XML

TestList.java класс

@XStreamAlias("Assets")
public class TestList extends ParentObject {

@XStreamImplicit(itemFieldName = "item")
protected List<Item> item= new ArrayList<Item>();

public void add(Item item) {
item.add(item);
}

public List<Item> getItems() {
    if(item== null)
        return new ArrayList<Item>();
    else
        return item;
}

@Override
public String getStringData() {
StringBuilder builder = new StringBuilder();

for (Item item : items) {
    builder.append(item.getStringData());
    builder.append("---------------\n");
}

return builder.toString();
}

@Override
public String getDataType() {
// TODO Auto-generated method stub
return null;
}

Item.java класс:

 @XStreamAlias("Item")
public class Item extends ParentItem {
@XStreamAsAttribute
public String access_test;

@XStreamAsAttribute
public int test_num;

@XStreamAsAttribute
public int test_type;

@XStreamAsAttribute
public boolean tst_item;

@XStreamAsAttribute
public int test_test_est;

@XStreamAlias("eset_test")
public List<Integer> eset_test;

И, конечно, у меня есть геттеры и сеттеры, которых я здесь не включаю.

Исключение:

com.thoughtworks.xstream.security.ForbiddenClassException: com.test.cp.test123.pojo.TestList
    at com.thoughtworks.xstream.security.NoTypePermission.allows(NoTypePermission.java:26)
    at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:74)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:47)
    at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType(HierarchicalStreams.java:29)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:133)
    at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1206)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1190)
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1061)

6 ответов

Использование его в качестве основы безопасности

Вам необходимо настроить платформу безопасности в XStream.

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

Я стараюсь быть осторожным. Так что я разрешил только основы, те, которые принадлежат мне, и некоторые, которые использую.

Основы

Как указано в других ответах, начните с использования значения по умолчанию

      XStream xstream = new XStream();
XStream.setupDefaultSecurity(xstream);

Как указано в документации, « он инициализирует экземпляр XStream с белым списком хорошо известных и простых типов среды выполнения Java ».

Те, что мои

Я разрешил посылкой:

      xstream.allowTypesByWildcard(new String[] { 
        "com.mydomain.mynewapp.**",
        "com.mydomain.utilitylibraries.**
        });

Некоторые я использую

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

      xstream.allowTypes(new Class[] {
        com.google.common.base.Present.class,
        org.apache.commons.math3.random.GaussianRandomGenerator.class
        });

Чтобы избавиться от исключения в вопросе, OP может добавить что-то вроде:

      xstream.allowTypes(new Class[] {com.test.cp.test123.pojo.TestList.class});

Заключение

XStream позволяет вам настроить безопасность десериализации ваших классов настолько жестко, насколько вы этого хотите. Наверное, хватит самого минимума. Но недостаточно не задать вам вопрос: «Насколько жесткой должна быть эта безопасность?» Как только вы поразмыслите над этим вопросом, действуйте соответственно.

http://x-stream.github.io/security.html

Попробуйте ограничить до минимума необходимых разрешений.

Это сняло бы все ограничения (см. Ссылку выше): xstream.addPermission(AnyTypePermission.ANY);

После ответа @Kokeb у меня был spring bean со следующей строкой кодов:

        XStreamMarshaller marshaller = new XStreamMarshaller();
  Map<String, Class<MyMessage>> aliases = new HashMap<>();
  aliases.put("myMessages", MyMessage.class);
  marshaller.setAliases(aliases);

Я добавил:

       marshaller.getXStream().allowTypes(new Class[]{MyMessage.class});

и это решило проблему.

немного контекста, я использовал XStream для проекта с весенним пакетом, весенней интеграцией и ActiveMQ, я установил bean-компонент, который преобразует сообщения ActiveMQ в класс сообщений. полный боб:

          @Bean
    public MessageConverter messageConverter() {
        XStreamMarshaller marshaller = new XStreamMarshaller();
        Map<String, Class< MyMessage >> aliases = new HashMap<>();
        aliases.put("myMessages", MyMessage.class);
        marshaller.setAliases(aliases);
        marshaller.getXStream().allowTypes(new Class[]{MyMessage.class});

        MarshallingMessageConverter messageConverter = new MarshallingMessageConverter(marshaller);
        messageConverter.setTargetType(MessageType.TEXT);
        return messageConverter;
    }

Я решил свою проблему, используя что-то вроде:

Class<?>[] classes = new Class[] { TestList.class, Item.class, ... };
XStream xstream = new XStream();
XStream.setupDefaultSecurity(xstream);
xstream.allowTypes(classes);

Я также столкнулся с этой проблемой и получил решение, добавив AnyTypePermission,

      xstream.addPermission(AnyTypePermission.ANY);

У меня есть производный класс XStreamMarshaller, где метод "XStreamMarshaller.supports " переопределен. Я добавил getXStream().allowTypes(classes), см. фрагмент ниже.

      @Override
public boolean supports(Class<?> clazz) {
    Class<?>[] classes = new Class[] {clazz};
    getXStream().processAnnotations(classes);
    getXStream().allowTypes(classes);
    return super. Supports(clazz);
}
Другие вопросы по тегам