x-stream / xstream

Serialize Java objects to XML and back again.
http://x-stream.github.io
Other
749 stars 227 forks source link

Xstream-1.4.18 Converting java object to string #264

Closed vijayanandof closed 3 years ago

vijayanandof commented 3 years ago

We were using below logic to convert Java Object to XML. XStream xstream = new XStream(); String xml = xstream.toXML(JavaObject); With upgrade to 1.4.18 we are facing below exception:

---- Debugging information ---- cause-exception : com.thoughtworks.xstream.security.ForbiddenClassException cause-message : com.our.class class : java.util.ArrayList required-type : java.util.ArrayList converter-type : com.thoughtworks.xstream.converters.collections.CollectionConverter path : /list/com.our.class line number : 1 version : 5.3.4

We tried to whitelist our class, with example given in documentation

            XStream xstream = new XStream();
        xstream.addPermission(NoTypePermission.NONE);
        xstream.addPermission(NullPermission.NULL);
        xstream.addPermission(PrimitiveTypePermission.PRIMITIVES);
        xstream.allowTypeHierarchy(Collection.class);
        xstream.allowTypes(new Class[] {java.util.ArrayList.class, 
                com.our.class});
        return xstream;

After whitelisting too, I'm facing the same ForbiddenClassException, can someone help out with this?

joehni commented 3 years ago

Hi,

yes, this is, how it works. At least with official XStream versions. However, I wonder what you are using. There's no version 5.3.4 of XStream. And, on top of it, XStream does its checks only at unmarshalling time.

Regards, Jörg

sanderino666 commented 3 years ago

Hi @joehni,

We are facing the same issue. We are using Axon (4.5.3) which uses Xstream to serialize. Due to to CVE-2021-39139 we bumped from 1.4.17 to 1.4.18 where the Xstream.setupDefaultSecurity is deprecated and the method does nothing anymore which causes a lot of regression.

public void configure(XStreamSerializer serializer) {
    XStream.setupDefaultSecurity(serializer.getXStream());
    serializer.getXStream().addPermission(AnyTypePermission.ANY);
  }

Wouldn't it be better to have the method itself be deprecated in 1.4.x and remove it in 1.5?

As a workaround for now we copied the content of Xstream.setupDefaultSecurity to a local method.

vijayanandof commented 3 years ago

Hi,

yes, this is, how it works. At least with official XStream versions. However, I wonder what you are using. There's no version 5.3.4 of XStream. And, on top of it, XStream does its checks only at unmarshalling time.

Regards, Jörg

Xstream version we are upgrading to is 1.4.18 Spring version 5.3.4

For unmarshalling we are using XStreamMarshaller

List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
        MarshallingHttpMessageConverter marshallingHttpConverter = new MarshallingHttpMessageConverter(**customizeXStreamMarshaller**());
        marshallingHttpConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_XML));
        messageConverters.add(marshallingHttpConverter);

    private XStreamMarshaller **customizeXStreamMarshaller**() {
        return new XStreamMarshaller() {
            @Override
            protected void customizeXStream(XStream xstream) {
                xstream.denyTypes(new Class[] {void.class, Void.class});
            }
        };
    }

Any way to get around this by changing customizeXStreamMarshaller for latest version?

Vishavjeet6 commented 3 years ago

Facing same problem any workaround?

joehni commented 3 years ago

Again: A vanilla XStream never throws a ForbiddenClassException at marshaling nor does it claim to be version 5.4.3 or whatever. If XStream behaves so differently in Spring, you must ask those people, what they have done to the provided XStream instance.

joehni commented 3 years ago

Hi @joehni,

We are facing the same issue. We are using Axon (4.5.3) which uses Xstream to serialize. Due to to CVE-2021-39139 we bumped from 1.4.17 to 1.4.18 where the Xstream.setupDefaultSecurity is deprecated and the method does nothing anymore which causes a lot of regression.

public void configure(XStreamSerializer serializer) {
    XStream.setupDefaultSecurity(serializer.getXStream());
    serializer.getXStream().addPermission(AnyTypePermission.ANY);
  }

Wouldn't it be better to have the method itself be deprecated in 1.4.x and remove it in 1.5?

As a workaround for now we copied the content of Xstream.setupDefaultSecurity to a local method.

Gosh, why do you care about the XStream version anyway with this code? You could simply remove the call of setupDefaultSecurity here, because in the next line you allow anything anyway, wiping out any previous security setting. You actually made the instance vulnerable to any known security issue yourself. Congrats.

vijayanandof commented 3 years ago

Again: A vanilla XStream never throws a ForbiddenClassException at marshaling nor does it claim to be version 5.4.3 or whatever. If XStream behaves so differently in Spring, you must ask those people, what they have done to the provided XStream instance.

Hi @joehni My mistake initially thought issue happens with marshalling, but this issue happens only when doing unmarshalling. The version shared (5.3.4) is spring-oxm which internally uses XStream.(XStreamMarshaller) We are discussing with Spring peeps as well.

Thanks for your inputs, Vijay

sanderino666 commented 3 years ago

@joehni bad example (line below was me trying out stuff) but no need to get defensive. Sorry that we are using your library and asking questions when facing regression in a patch version. It's labeled "question" for a reason.

joehni commented 3 years ago

@sanderino666 OK, I really assumed this example to be real code.

See, the original intent was to keep the blacklist for XStream 1.4.x and use a whitelist for 1.5.x. Since the Security Framework is initialized in the constructor, we provided the setupDefaultSecurity method to allow a smooth transition. Any user of 1.4.x could call the method directly after the construction of a new instance and setup the XStream instance in the same way it will happen in 1.5.0. The method there has been vanilla since introducing it.

I maintain XStream in my spare time. However, after spending now months documenting security issued and writing reports only (instead of working toward a version 1.5.0), my level of frustration is quite on the top. The only solution to change the situation, was to accept that the blacklist will never be secure at all (it handled anyway only issued with class types of the Java runtime) and to apply the whitelist of 1.5.0 now also to 1.4.18. In the long run it seems the best for XStream and its users.

Now, I don't know what the XStreamSerializer in Spring really does. You should be aware though that XStream separates clearly between configuration phase and runtime. Once an instance had been used for marshalling, you should never enter configuration phase again and reuse it with a different configuration, since the internal cache was built based on the original configuration. Your current problems seem to indicate, that this is the case.

Hope this helps, Jörg

sanderino666 commented 3 years ago

@joehni yes this helps and I can imagine your frustration at the moment. It is pretty awesome that you are maintaining this lib, especially in your free time.

I completely agree with your initial intent to keep the blacklist in 1.4 and move to a whitelist in 1.5 and I know the frustration of having to backport these things to earlier versions (had to maintain a product with an N - 2 major policy).

So, keep up the good work and don't forget to take care of yourself. We sometimes forget there is more to life than work :-)

sagga001 commented 3 years ago

@sanderino666 Did you find any way out? I am getting lot of regression once I moved to 1.4.18 from 1.4.17..Most of my app TC(429) went into failure at unmarshalling process.Can you please share the link where you posted issue at spring page?

Caused by: com.thoughtworks.xstream.security.ForbiddenClassException: com.alcatel.ni.commands.framework.address.LineAddress 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:125)

public static Object fromXML(String value) { value = value.replace("Address-1\"", "Address$1\""); return XSTREAM.fromXML(value); }

sanderino666 commented 3 years ago

@sagga001 there are 2 separate cases here. @vijayanandof is using spring-oxm 5.3.4 and I am using Axon 4.5.3. Having checked Axon there is already an open PR to bump from 1.4.17 to 1.4.18 in Axon 4.5.4 (https://github.com/AxonFramework/AxonFramework/pull/1917) so we decided to wait for the next Axon release.

sagga001 commented 3 years ago

@sanderino666 My spring-oxm version is 5.3.7. @vijayanandof Any update on this issue ? Did you get any information ?

vijayanandof commented 3 years ago

@sagga001 I have raised a ticket for spring-oxm https://github.com/spring-projects/spring-framework/issues/27342 and there a feature for "Convenient configuration of type permissions for XStream 1.4.18" in upcoming release in spring-oxm. Currently didn't find any workaround.

sagga001 commented 3 years ago

@joehni Can you please suggest on this ? According to @vijayanandof post on Spring they inform that issue could be with Xstream latest change related to permissions

joehni commented 3 years ago

@sagga001: There is no workaround. XStream implements now a whitelist, since a blacklist is insecure. And if Jürgen suggest to use an AnyTypePermission, then he implements on his own a blacklist with no denials at all and he opens that XStream instance for all known CVE issues. And remember, this list covers only the ones found until now with types in the Java runtime. I wonder, what Spring will do generate a secure application instead.

sagga001 commented 3 years ago

Finally this version change from 1.4.17 to 1.4.18 works for me..We migrated to spring 5.3.10 and after that I don't see any issue with xstream.

joehni commented 3 years ago

Thanks for the feedback.

Shikari0744 commented 2 years ago

Finally this version change from 1.4.17 to 1.4.18 works for me..We migrated to spring 5.3.10 and after that I don't see any issue with xstream.

I had similar issue and I am using spring 5.3.18v. Any Idea ? https://github.com/x-stream/xstream/issues/302

sagga001 commented 2 years ago

Finally this version change from 1.4.17 to 1.4.18 works for me..We migrated to spring 5.3.10 and after that I don't see any issue with xstream.

I had similar issue and I am using spring 5.3.18v. Any Idea ? #302

I had to finally implement XStream list by using various methods.You can bypass the methods/classes etc which come in call.It was a regression for us and had to fix in entire code. eg xstream.allowTypesByWildcard(new String[] {"src.abc**"})

Shikari0744 commented 2 years ago

If I bypass the class like :

xStreamSerializer.addPermission(NoTypePermission.NONE);
Class<?>[] classes = new Class[] {Status.class, Entry.class};
xStreamSerializer.allowTypes(classes);

Two problems with this, we will be open to vulnerabilities and its not working for me :<(

sagga001 commented 2 years ago

If I bypass the class like :

xStreamSerializer.addPermission(NoTypePermission.NONE);
Class<?>[] classes = new Class[] {Status.class, Entry.class};
xStreamSerializer.allowTypes(classes);

Two problems with this, we will be open to vulnerabilities and its not working for me :<(

Then u need to try different option like bypass package itself.For us also it took lot of time to identify the fixes.When we started bypassing classes then it was not just 1-2 class but list was not ending.Also I did not use below statement when I allowed types xStreamSerializer.addPermission(NoTypePermission.NONE);