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);
}