Java doesn't make exploitable RCEs more or less possible than any other programming language. Or do you have something to back this up beyond the common "Java be bad" trope?
Comparing Java Serialization with $language Serialization, and the usage of both of the languages, does Java have more RCEs per line written than $language? Or is it just a function of its popularity?
The java ecosystem has a frustrating habbit of solving problems with java's lack of expressiveness with layers of expression and templating languages, and has had some nasty RCE's as a result. (see: OGNL, freemarker)
I don't know if it's better or worse than other languages but let's not pretend it's not a problem.
Why would you need extended support for Java 8 to deploy a log4j patch? Oracle will happily take the money I’m sure but the log4j update is freely downloadable from
Apache.
Can't tell if this depends on certain user code - does one have to use SerializationUtils or JCache explicitly in order to be vulnerable, or does the vulnerability exist by default?
That's my take on it from reading so far. That's a massive mitigating factor for exploitation, imo.
Log4Shell was painful because people were using the library as it was intended to be used (a logger takes strings that are possibly attacked controllable). This will not be as bad simply because it won't be easily exploitable to the same degree.
The blog post on Kendra looks like a draft hoping for an actual confirmation/poc to come up, the mitigation just explains manually how to replicate the PR #28075.
Edit: They just translated the chinese post you can find linked here.
A comment [0] on the commit of that PR points to this site [1]. This site mentions that the vulnerability is similar to CVE-2010-1622 [2, 3]. Maybe this could help finding the issue, toegether with the recommended actions and mentioned classes (CachedIntrospectionResults, CacheResultInterceptor).
"How is this being upvoted without an actual POC and using language like “possible” and “may”?"
I appreciate being made aware of the speculation given the ubiquity of Spring. Those that claim an RCE in core Spring would be an order of magnitude worse than Log4Shell aren't wrong.
I'm poking around at the Spring code and posting some notes about what I find on Twitter[0].
I'm not a Java expert so if anybody feels like chiming in to help connect the dots for others, please feel free. It's late over here so I'm just doing my best to help determine if this is a real problem or just fear mongering.
I wrote a basic vulnerable app on GitHub[1] that is helpful for finding the most "simple" payload that could trigger this RCE. If anybody with better Java skills than myself would be willing to poke at this for a sec, that'd be super appreciated.
I was using this guide[2] with the ysoserial section to generate a deserialzation payload for this. I still don't have enough Java-fu to understand how to get that to fire though, and it's 3am so my brain is shot. Perhaps with these pointers somebody else can figure out that part to help sort out the impact around this possible RCE.
I don't think there's any vulnerability in your repo as it is. It's not deserializing attacker controlled data, it's deserializing a string which was serialised by the application. There could be a vulnerability if, instead of accepting a String, the controller accepted some other class, which itself had custom serialisation logic which was vulnerable.
This is the pattern that's in the Spring code, which is why I wrote it there.
I agree with you though that it seems non-obvious.
My thought is that it's possible to build a payload that is able to go from "serialize(string) -> deserialize(string) -> object".
If it's possible to do that, then there is some possibility that there is an RCE here. But I'd still have to poke at the @CacheResult annotation to understand what a vulnerable usage would look like.
First thing is first though. Start with the simplest case. Prove or disprove exploitability before moving up the chain.
This doesn't look like a CVE based on this. To execute this you'd have to post in the class file, deserialise and then exec. All of this takes explicit additional code. This looks to be the same as any other language where you would let a user upload code and then just exec it, not something you really do accidentally and not part of core spring (I'm hoping). @Serializable is going to send the fields not the methods, so again you'd usually have deserialise to a known object which rehydrates, and then exec.
I struggle to see that usage in any std spring app which is going to use say jackson/json parsers typically and is hooked of content-type field which has to be mapped for usage really. If there's other vectors to trigger even with the object you'd still then have to invoke which would take additional explicit code. Using object deserialisation would be pretty uncommon (ie non existent) hooked up to http stack. Json, XML, yaml parsers etc are different libs. To get this to CVE you'd have to trigger this automatically somehow through the spring request processing stack and then say invoke the object with vulnerabilities in java's core deserialisation libs which I'm assuming is relatively solid and verified given it's key role in java, see java security manager in jvm for actions like dynamic class loading etc.
For this to get to CVE issue it would be if there was a vector where spring can take a request with a class file/location eg urlclassloader bypass a bunch of security checks and get it to run, which again java security manager will not allow typically. As it stands in the bug, that's not called out as a vector and more of a don't do silly things, sure we'll mark it as deprecated tone. There may be something somewhere else, but as it stands I read this issue as don't exec untrusted code in your webapp which should be true in any language. Your example is explicitly coding to do this, not something any typical spring app does. I guess use cases like job interview, code testing tools might do this. but it's still going to be execing against a specific interface/abstraction typically on the server side, ie still not unknown code. Ie the methods live in server side classes that correspond to the type the serialised class is deserialised to, no code transmitted so can't inject behaviour simply by deserialising
Thanks for the detailed info about this! I'll go poke my head in on this again now that I'm awake and verify all of this. Some people are claiming POCs so I'm very curious to dig in!
Just because something is popular doesn't mean it's going to be bullet proof, btw. People miss stuff regularly like in log4j. Digging deep is where the juiciest bugs are found!
The Spring code isn't restricted to strings, it will accept any type. So you don't need to find unsafe string serialisation to get an RCE; what you need is some type which is unsafe when deserializing the output of its own serialise function (and for an attacker controlled instance of this type to be passed to this Spring method)
It looks like they are mixing it up with CVE-2022-22963 related to spring cloud[1] from a few days ago and one of the members of the Spring project is reporting that there is no vulnerability associated with the deserialization fix everyone (the chinese OP, the eng posts) is referring to.
Seems unlikely. The commit this speculates is the fix for the supposed RCE does not appear to change the behaviour of Spring in any way - it just refactors some code into a seperate function, adds a unit test for that function, and marks the use of serialization-related functions as depreciated due to their history of RCE issues. The apparent reason for the refactoring is to avoid triggering the depreciation warning for one particular use of serialization which should be safe (it serializes and then immediately deserializes a non-attacker-controlled object).
37 comments
[ 4.3 ms ] story [ 40.0 ms ] threadLooking at Github and uses of SerializationUtils.deserialize this is going to be painful.
I don't know if it's better or worse than other languages but let's not pretend it's not a problem.
https://www.sourceclear.com/vulnerability-database
Everything is a mess, no matter the language.
https://news.ycombinator.com/item?id=30850400
However the original image is deleted from twitter.
If it is true, you will need to downgrade to JDK8. But to solve Log4J issue, you need JDK9+...
Log4Shell was painful because people were using the library as it was intended to be used (a logger takes strings that are possibly attacked controllable). This will not be as bad simply because it won't be easily exploitable to the same degree.
The commit just looks like sane defensive programming. Serialisation is a known source of RCEs, so they deprecate its use.
Edit: They just translated the chinese post you can find linked here.
[1] https://github.com/spring-projects/spring-framework/pull/280...
[0]: https://github.com/spring-projects/spring-framework/commit/7...
[1]: https://mp.weixin.qq.com/s/P-NEJzUUjIyemkSe_RbicQ
[2]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-1622
[3]: https://www.exploit-db.com/exploits/13918
How is this being upvoted without an actual POC and using language like “possible” and “may”?
I appreciate being made aware of the speculation given the ubiquity of Spring. Those that claim an RCE in core Spring would be an order of magnitude worse than Log4Shell aren't wrong.
I'm poking around at the Spring code and posting some notes about what I find on Twitter[0].
I'm not a Java expert so if anybody feels like chiming in to help connect the dots for others, please feel free. It's late over here so I'm just doing my best to help determine if this is a real problem or just fear mongering.
0: https://twitter.com/LunaSecIO/status/1509084844042510336
EDIT:
I wrote a basic vulnerable app on GitHub[1] that is helpful for finding the most "simple" payload that could trigger this RCE. If anybody with better Java skills than myself would be willing to poke at this for a sec, that'd be super appreciated.
I was using this guide[2] with the ysoserial section to generate a deserialzation payload for this. I still don't have enough Java-fu to understand how to get that to fire though, and it's 3am so my brain is shot. Perhaps with these pointers somebody else can figure out that part to help sort out the impact around this possible RCE.
1: https://github.com/lunasec-io/spring-rce-vulnerable-app
2: https://foxglovesecurity.com/2015/11/06/what-do-weblogic-web...
By LunaSec IIRC.
I agree with you though that it seems non-obvious.
My thought is that it's possible to build a payload that is able to go from "serialize(string) -> deserialize(string) -> object".
If it's possible to do that, then there is some possibility that there is an RCE here. But I'd still have to poke at the @CacheResult annotation to understand what a vulnerable usage would look like.
First thing is first though. Start with the simplest case. Prove or disprove exploitability before moving up the chain.
I struggle to see that usage in any std spring app which is going to use say jackson/json parsers typically and is hooked of content-type field which has to be mapped for usage really. If there's other vectors to trigger even with the object you'd still then have to invoke which would take additional explicit code. Using object deserialisation would be pretty uncommon (ie non existent) hooked up to http stack. Json, XML, yaml parsers etc are different libs. To get this to CVE you'd have to trigger this automatically somehow through the spring request processing stack and then say invoke the object with vulnerabilities in java's core deserialisation libs which I'm assuming is relatively solid and verified given it's key role in java, see java security manager in jvm for actions like dynamic class loading etc.
From https://github.com/spring-projects/spring-framework/pull/280... "The core Spring Framework does not use SerializationUtils to deserialize objects from untrusted sources." They talk about use against a cache but again rule out CVE.
For this to get to CVE issue it would be if there was a vector where spring can take a request with a class file/location eg urlclassloader bypass a bunch of security checks and get it to run, which again java security manager will not allow typically. As it stands in the bug, that's not called out as a vector and more of a don't do silly things, sure we'll mark it as deprecated tone. There may be something somewhere else, but as it stands I read this issue as don't exec untrusted code in your webapp which should be true in any language. Your example is explicitly coding to do this, not something any typical spring app does. I guess use cases like job interview, code testing tools might do this. but it's still going to be execing against a specific interface/abstraction typically on the server side, ie still not unknown code. Ie the methods live in server side classes that correspond to the type the serialised class is deserialised to, no code transmitted so can't inject behaviour simply by deserialising
Just because something is popular doesn't mean it's going to be bullet proof, btw. People miss stuff regularly like in log4j. Digging deep is where the juiciest bugs are found!
https://twitter.com/Ax_Sharma/status/1509103877978824707
[1] https://spring.io/blog/2022/03/29/cve-report-published-for-s...
[2] https://github.com/spring-projects/spring-framework/pull/280...
https://spring.io/blog/2022/03/31/spring-framework-rce-early...
You're probably looking for "denied".