-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Java: CWE-502 Unsafe JSON deserialization with Gson, Flexjson, Jabsorb and JoddJson #5954
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Java: CWE-502 Unsafe JSON deserialization with Gson, Flexjson, Jabsorb and JoddJson #5954
Conversation
java/ql/src/semmle/code/java/security/UnsafeDeserialization.qll
Outdated
Show resolved
Hide resolved
java/ql/src/semmle/code/java/security/UnsafeDeserialization.qll
Outdated
Show resolved
Hide resolved
java/ql/src/semmle/code/java/security/UnsafeDeserialization.qll
Outdated
Show resolved
Hide resolved
40e38ff
to
ce94c86
Compare
bcf9ed5
to
e879ae7
Compare
I've started evaluating this as-is, but for future reference, could the new sanititzer be implemented with |
Thanks @smowton for reviewing this PR. I'll make the change of moving |
@smowton I've made the change. Please review and let me know if more changes are needed. Thanks. |
@luchua-bc please rebase this now that the other unsafe-deserialization PRs have landed |
0a1e6aa
to
1c2c438
Compare
@smowton I've done the rebase. Please review. Thanks. |
File "ql/java/ql/test/stubs/joddjson-6.0.3/jodd/json/JsonParser.java" contains a non-ASCII character at the location marked with
File "ql/java/ql/src/semmle/code/java/frameworks/google/Gson.qll" contains a non-ASCII character at the location marked with
ASCII check failed! These will probably be non-breaking spaces or similar |
@smowton I've fixed those two issues - one caused by the Windows style double quotes in the stub source file, and the other one was a Unicode character in Please run the ASCII check again. Thanks. |
Also this needs a rebase |
I've made the changes on the rebased branch so it seems that another rebase is not required. Please advise if so. Thanks. |
@luchua-bc there are still conflicts with |
I rebased my branch java/unsafe-gson-flexjson-joddjson-deserialization onto the main. Sorry that there are still some conflicts. I will try to rebase again. |
A few questions:
|
What I did is on my branch:
Please let me know if my procedure is not correct. Thanks. |
You need a |
Hi @smowton, Please find my comments below:
If a class is non-final and one of its subclasses is vulnerable, attacker can feed a malicious payload with an object of the vulnerable subclass.
If
I will test all the other overloads and verify. I have assumed using
I will test and verify.
As this method is not widely used, I have tested it yet. I will test and verify then report back. |
fed7142
to
d0854e9
Compare
d0854e9
to
42948c6
Compare
Hi @smowton, For questions 3-5:
I've verified that the other overloads of
And I've rebased the code. Please review. Thanks, |
java/ql/src/semmle/code/java/security/UnsafeDeserialization.qll
Outdated
Show resolved
Hide resolved
That's not quite what I meant regarding Gson, but at this point it's faster to just write what I mean rather than try to explain further. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some other improvements, but happy to make these myself. Would be glad to hear your take re: the false-positive vs. false-negative risk and non-final
classes.
| | ||
dma.getMethod() instanceof DeserializerUseMethod and | ||
( | ||
ma.getQualifier() = dma or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth noting that
JSONDeserializer<Person> jsd = new flexjson.JSONDeserializer<Person>();
jsd.use(null, Person.class);
jsd.deserialize(json);
is also safe. Without taking on all the cost of a subsidiary Configuration, it might be best to achieve this by modelling all the use(...)
methods as having value-flow from qualifier to return value, then using localFlow(any(MethodAccess ma | ma.getMethod() instanceof DeserializerUseMethod).getQualifier(), ...)
This would be best achieved by something like adding a lib file that is imported from ExternalFlow.qll that contains:
class FlexJsonModels extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"flexjson;JSONDeserializer;false;use;;;Argument[-1];ReturnValue;value"
]
}
}
This says that the use
methods are fluent (i.e., they return this
), and enables localFlow
to do the rest of the work for us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great. This looks like a nice solution and I will learn a new technique from your final version. Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@smowton - for this one, will you make the change or do you want me to make the change following your code snippet? Please advise. Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll pick it up from here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @smowton:-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding Flexjson, it appears only usage of use(String, ...)
where the path is null
or use(ObjectFactory, String...)
where the string varargs (or array) contains null
is safe. In all other cases (even empty String as Path) it applies only to sub elements of the root JSON value. For example, the following has no effect and calls the malicious constructor:
new JSONDeserializer<Safe>()
// Only applies to JSON path 'abc'
.use("abc", Safe.class)
// Only affects *how* type is deserialized, but not *as which* type JSON is deserialized
.use(Safe.class, new ExistingObjectFactory(new Safe()))
.deserialize(json);
Additionally, if I see that correctly even if you explicitly specify a type, the application might still be vulnerable if that type has fields or setter methods with type Object
(or similar), but that might be out of scope for this pull request.
And not really relevant for this query, but Flexjson initializes arbitrary classes in case no thread context class loader is set (there might be one by default), see https://sourceforge.net/p/flexjson/code/162/tree/trunk/src/main/java/flexjson/ObjectBinder.java#l245. That code does not appear to be in the latest commits (maybe it was just moved somewhere else), but they have not been released anyway.
@Marcono1234 Thanks for reviewing the PR and I've made requested changes. Please review. |
@smowton and @Marcono1234 - with the most recent change, do we still need to revamp the query using |
This is partly extracted from github#5954
Jabsorb support factored with existing Jackson support and split off as #6419 |
Thanks @smowton. |
Part 2: Jodd JSON: #6434 |
Part 3: #6456 Part 4: #6463 That last one implements Gson support and takes quite a different approach, introducing a single step from an Intent to the Parcel parameter of a |
Wow! That's a lot of changes. Thanks @smowton a lot for your help. For future PRs, I will submit one PR per library/query. |
That's useful, especially when targeting non-experimental which is always going to require extra effort on our part. |
Last bits of this are now merged |
Thanks @smowton a lot for all your help with this complex and comprehensive PR, which is literally 4 PRs:-). |
Deserialization of untrusted data with JSON frameworks could introduce critical security vulnerabilities such as Remote Code Execution (RCE).
This query checks four popular JSON frameworks - Gson, Flexjson, JoddJson, and Jabsorb and detects the following vulnerabilities:
Some known CVEs and issues related to these JSON implementations are:
Please consider to merge the PR. Thanks.