-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Java LDAP Injection (CWE-90) #2651
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
Conversation
JNDI and UnboundID sinks JNDI, UnboundID and Spring LDAP sanitizers
Spring LDAP sink
Apache LDAP API sink
Consider DNs as injection points as well Add more taint steps
Refactoring
Autoformat
aschackmull
left a comment
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.
QL code generally looks good, but I've left a few inline comments.
Refactoring according to review comments.
|
I refactored the QL code as you suggested. BTW, I have a Java class with various types of LDAP injection vulnerabilities as well as good code. I use it to test this query. I'm not sure how can I use it here, so I'll just link it: https://gist.github.com/ggolawski/bb8e501253e850c1c228f88b86fc7acc |
felicitymay
left a comment
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 for including a help topic with your query - it's a great help to users. It's also good to have lots of examples and references.
I've made some suggestions to make the help more consistent with existing topics, and with the aim of simplifying some of the longer sentences. In one place, I wasn't entirely sure of your original meaning, so please review that suggestion with particular care. The rest of the topic seemed very clear.
Co-Authored-By: Felicity Chapman <felicitymay@github.com>
|
Thanks for the refactor - QL code is looking good now. The test that you've linked in the gist is definitely something that we want to include - we have a unit test framework where it should fit in, but the tests should be self-contained without dependencies to third-party libraries, which means that for cases like these we usually add interface stubs. I'll look into taking care of that, so no need to worry about it (also, since you can't quite execute the unit tests yet - the external tooling for that will be available soon!). As soon as I've got the test ready I'll let you know, so you can review the expected output. |
|
Thanks @aschackmull for taking care of unit tests. I'll check the output once the tests are ready. |
|
I've added your unit test along with the necessary library stubs, options file, and .expected file as a PR against your PR: ggolawski#3 |
Co-Authored-By: Felicity Chapman <felicitymay@github.com>
|
If I count correctly, there're 2 false positives and 2 false negatives. They all can be fixed by slightly modifying the stubs. I've commented the relevant code in ggolawski#3 with the details. |
|
I've fixed it on ggolawski#3. |
|
From the documentation point of view, this all looks ready to merge 👍 |
Java: Add unit test for ldap injection.
|
Thanks for fixing the tests. I've merged ggolawski#3. |
|
Hi, where in the coder could I find the value of variable such taintedDN or taintedFilter ? I quickly had a look at the PR, wasn't able to find it. Thanks ! |
|
Hi, I guess you're referring to the examples from the PR description. This CodeQL query detects such flows by statically analyzing the code. It doesn't check the actual variable values - this would be dynamic analysis and would require the code to be executed. I hope it helps. |
|
Hi, do you have example of such tainted values ? For instance, if you look on the internet, you find things like (&(uid=xxxx)(?)(userPassword=yyy)) which simply won't be accepted by Apache LDAP API (we do reject such construct which is not valid by RFC 4515, so it can't be used to try some LDAP injection to gain access to a web site, for instance. I'm asking because I'm interested in seeing if there are means to abuse the Apache LDAP API and if so, to try to fix it (if possible). Many thanks ! |
|
Hi, You can find some payloads here: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/LDAP%20Injection The first example results in 2 valid filters and I'm not sure if it would be accepted by Apache LDAP API: But the second example results in a single valid filter which would be accepted, wouldn't it?: |
|
Hi, First, the userPassword attribute is rarely stored in clear text (for obvious security reasons). The standard form is hashed, and the server compares a hashed version of what is provided by a user during a bind with what is stored. Any request that fetches this attribute will returns the hashed value, which will only be 'good' if you want to conduct a rainbow attack on it. Regarding the samples, a request containing something like (1=0) will be rejected by a server that checks the attributes as '1' is not a valid attributeType. Regardless, what is troubling is to expect an application using a login form with user/password fields to send a search request, instead of doing a bind, which is the base operation when it comes to validate a login... Of couse, we are not short of such bad web application out there ;-) |
|
Exactly, everything depends on the application and how the results are interpreted :-) In the second example in my previous comment, if the code would execute the search and then check if it returned anything (assuming that the credentials are correct if it did), it would be possible to bypass this authentication. And In general, using user provided input to construct search filter without sanitizing it is always a bad idea. |
This PR adds a query to detect LDAP Injections in Java. Plain Java JNDI, UnboundID, Spring LDAP and Apache LDAP API are covered.
This query detects the following LDAP Injection variants:
JNDI
DirContext.searchwith tainted DN or filter, for example:DirContext.searchwith taintedLdapName, for example:DirContext.searchwith taintedRdn, for example:UnboundID
LDAPConnection.searchwith tainted DN or filter, for example:Filter.createwith tainted filter, for example:SearchRequestwith tainted DN or filter, for example:LDAPConnection.searchForEntrywith tainted DN or filter, for example:LDAPConnection.asyncSearchwithSearchRequestwith tainted DN or filter, for example:Spring LDAP
LdapTemplate.search,LdapTemplate.authenticate,LdapTemplate.searchForObject,LdapTemplate.findOne,LdapTemplate.findorLdapTemplate.searchForContextwith tainted DN or filter, for example:LdapNameBuilderwith tainted DN, for example:LdapQueryBuilderwith tainted filter or DN, for example:LdapUtils.newLdapNamewith tainted DN, for example:HardcodedFilterwith tainted filter, for example:Apache LDAP API
LdapConnection.searchwith tainted DN or filter, for example:Dnwith tainted DN, for example:SearchRequestwith tainted DN or filter, for example: