Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
f5dc033
Java: Improve modelling of Spring request methods
lcartey May 15, 2020
4300bc8
Java: Update RemoteFlowSource to use improve Spring request parameter
lcartey May 15, 2020
6de2b93
Java: Add SpringWebRequest to RemoteTaintedMethod
lcartey May 15, 2020
7c4251d
Java: Add flow out of Map and List
lcartey May 15, 2020
bfcc06d
Java: Improve Spring controller modelling
lcartey May 17, 2020
fd2cd60
Java: Modelling of the Spring HTTP classes.
lcartey May 17, 2020
1d12340
Java: Model Spring @ResponseBody methods.
lcartey May 17, 2020
7d555a7
Java: Track flow through HttpEntity and ResponseEntity
lcartey May 17, 2020
c59042f
Java: Taint tracking through String.replace(all)?
lcartey May 17, 2020
8057dff
Java: Add Spring XSS sinks
lcartey May 17, 2020
f6a99cb
Java: Model produces parameter to RequestMapping attribute.
lcartey May 17, 2020
e2cec58
Java: XSS - ignore Spring sinks when content-type is safe.
lcartey May 17, 2020
f6b2acc
Java: Model ResponseEntity.BodyBuilder
lcartey May 17, 2020
0db7cea
Java: Model taint flow through ResponseEntity.
lcartey May 17, 2020
8bd5f74
Java: SpringController - handle non-string literal produces values.
lcartey May 17, 2020
8678d5f
Java: Model untrusted user data types
lcartey May 17, 2020
93c28d4
Java: Add taint step to flow through Spring tainted user data class
lcartey May 17, 2020
cd6339f
Java: Add Spring flow out of HttpEntity and HttpHeader
lcartey May 17, 2020
9625e82
Java: Model Spring WebClients/RestTemplates.
lcartey May 17, 2020
f2edc53
Java: Add Spring RestTemplate return values to untrusted data types
lcartey May 17, 2020
2978af3
Java: Add RestTemplate as flow source.
lcartey May 17, 2020
6de612a
Java: Split SpringWebRequestGetMethod into its own class.
aschackmull Jul 3, 2020
a41c2d8
Java: Make a few predicates private and autoformat SpringController.
aschackmull Jul 6, 2020
2ae15f9
Java: Remove list, map, and StringReplaceMethod flow steps.
aschackmull Jul 6, 2020
2ce0921
Java: Clean up SpringHttp.qll
aschackmull Jul 6, 2020
a80e663
Java: Minor typo fix and autoformat
aschackmull Jul 6, 2020
5d8f9a7
Java: Misc grammar fixes.
aschackmull Jul 6, 2020
e6658c5
Java: Cleanup TaintTrackingUtil.qll
aschackmull Jul 6, 2020
5e9e7fe
Java: Add some qldoc and minor formatting.
aschackmull Jul 6, 2020
b06d1c7
Java: More qldoc and some formatting.
aschackmull Jul 6, 2020
ae21de9
Java: Misc grammar and formatting.
aschackmull Jul 6, 2020
f98460c
Java: Use SpringHttpEntity class.
aschackmull Jul 6, 2020
3fef5ca
Merge pull request #1 from aschackmull/java/spring-3653
lcartey Jul 7, 2020
48e4759
Merge branch 'master' into java/spring-3653-2
aschackmull Jul 8, 2020
581d496
Java: Fix LdapInjection qltest
aschackmull Jul 8, 2020
a4fe4f4
Java: Fix JndiInjection qltest
aschackmull Jul 8, 2020
b88ebd6
Java: Fix OgnlInjection qltest
aschackmull Jul 8, 2020
443c13d
Merge pull request #2 from aschackmull/java/spring-3653-2
lcartey Jul 8, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Java: Fix LdapInjection qltest
  • Loading branch information
aschackmull committed Jul 8, 2020
commit 581d496167bb2e6e228114bfad3ed1f68e97a921
454 changes: 227 additions & 227 deletions java/ql/test/query-tests/security/CWE-090/LdapInjection.expected

Large diffs are not rendered by default.

59 changes: 58 additions & 1 deletion java/ql/test/query-tests/security/CWE-090/LdapInjection.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,273 +34,327 @@
import org.springframework.ldap.support.LdapEncoder;
import org.springframework.ldap.support.LdapNameBuilder;
import org.springframework.ldap.support.LdapUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class LdapInjection {
// JNDI
@RequestMapping
public void testJndiBad1(@RequestParam String jBad, @RequestParam String jBadDN, DirContext ctx)
throws NamingException {
ctx.search("ou=system" + jBadDN, "(uid=" + jBad + ")", new SearchControls());
}

@RequestMapping
public void testJndiBad2(@RequestParam String jBad, @RequestParam String jBadDNName, InitialDirContext ctx)
throws NamingException {
ctx.search(new LdapName("ou=system" + jBadDNName), "(uid=" + jBad + ")", new SearchControls());
}

@RequestMapping
public void testJndiBad3(@RequestParam String jBad, @RequestParam String jOkDN, LdapContext ctx)
throws NamingException {
ctx.search(new LdapName(List.of(new Rdn("ou=" + jOkDN))), "(uid=" + jBad + ")", new SearchControls());
}

@RequestMapping
public void testJndiBad4(@RequestParam String jBadInitial, InitialLdapContext ctx)
throws NamingException {
ctx.search("ou=system", "(uid=" + jBadInitial + ")", new SearchControls());
}

@RequestMapping
public void testJndiBad5(@RequestParam String jBad, @RequestParam String jBadDNNameAdd, InitialDirContext ctx)
throws NamingException {
ctx.search(new LdapName("").addAll(new LdapName("ou=system" + jBadDNNameAdd)), "(uid=" + jBad + ")", new SearchControls());
}

@RequestMapping
public void testJndiBad6(@RequestParam String jBad, @RequestParam String jBadDNNameAdd2, InitialDirContext ctx)
throws NamingException {
LdapName name = new LdapName("");
name.addAll(new LdapName("ou=system" + jBadDNNameAdd2).getRdns());
ctx.search(new LdapName("").addAll(name), "(uid=" + jBad + ")", new SearchControls());
}

@RequestMapping
public void testJndiBad7(@RequestParam String jBad, @RequestParam String jBadDNNameToString, InitialDirContext ctx)
throws NamingException {
ctx.search(new LdapName("ou=system" + jBadDNNameToString).toString(), "(uid=" + jBad + ")", new SearchControls());
}

@RequestMapping
public void testJndiBad8(@RequestParam String jBad, @RequestParam String jBadDNNameClone, InitialDirContext ctx)
throws NamingException {
ctx.search((Name) new LdapName("ou=system" + jBadDNNameClone).clone(), "(uid=" + jBad + ")", new SearchControls());
}

@RequestMapping
public void testJndiOk1(@RequestParam String jOkFilterExpr, DirContext ctx) throws NamingException {
ctx.search("ou=system", "(uid={0})", new String[] { jOkFilterExpr }, new SearchControls());
}

@RequestMapping
public void testJndiOk2(@RequestParam String jOkAttribute, DirContext ctx) throws NamingException {
ctx.search("ou=system", new BasicAttributes(jOkAttribute, jOkAttribute));
}

// UnboundID
@RequestMapping
public void testUnboundBad1(@RequestParam String uBad, @RequestParam String uBadDN, LDAPConnection c)
throws LDAPSearchException {
c.search(null, "ou=system" + uBadDN, null, null, 1, 1, false, "(uid=" + uBad + ")");
}

@RequestMapping
public void testUnboundBad2(@RequestParam String uBadFilterCreate, LDAPConnection c) throws LDAPException {
c.search(null, "ou=system", null, null, 1, 1, false, Filter.create(uBadFilterCreate));
}

@RequestMapping
public void testUnboundBad3(@RequestParam String uBadROSearchRequest, @RequestParam String uBadROSRDN,
LDAPConnection c) throws LDAPException {
ReadOnlySearchRequest s = new SearchRequest(null, "ou=system" + uBadROSRDN, null, null, 1, 1, false,
"(uid=" + uBadROSearchRequest + ")");
c.search(s);
}

@RequestMapping
public void testUnboundBad4(@RequestParam String uBadSearchRequest, @RequestParam String uBadSRDN, LDAPConnection c)
throws LDAPException {
SearchRequest s = new SearchRequest(null, "ou=system" + uBadSRDN, null, null, 1, 1, false,
"(uid=" + uBadSearchRequest + ")");
c.search(s);
}

@RequestMapping
public void testUnboundBad5(@RequestParam String uBad, @RequestParam String uBadDNSFR, LDAPConnection c)
throws LDAPSearchException {
c.searchForEntry("ou=system" + uBadDNSFR, null, null, 1, false, "(uid=" + uBad + ")");
}

@RequestMapping
public void testUnboundBad6(@RequestParam String uBadROSearchRequestAsync, @RequestParam String uBadROSRDNAsync,
LDAPConnection c) throws LDAPException {
ReadOnlySearchRequest s = new SearchRequest(null, "ou=system" + uBadROSRDNAsync, null, null, 1, 1, false,
"(uid=" + uBadROSearchRequestAsync + ")");
c.asyncSearch(s);
}

@RequestMapping
public void testUnboundBad7(@RequestParam String uBadSearchRequestAsync, @RequestParam String uBadSRDNAsync, LDAPConnection c)
throws LDAPException {
SearchRequest s = new SearchRequest(null, "ou=system" + uBadSRDNAsync, null, null, 1, 1, false,
"(uid=" + uBadSearchRequestAsync + ")");
c.asyncSearch(s);
}

@RequestMapping
public void testUnboundBad8(@RequestParam String uBadFilterCreateNOT, LDAPConnection c) throws LDAPException {
c.search(null, "ou=system", null, null, 1, 1, false, Filter.createNOTFilter(Filter.create(uBadFilterCreateNOT)));
}

@RequestMapping
public void testUnboundBad9(@RequestParam String uBadFilterCreateToString, LDAPConnection c) throws LDAPException {
c.search(null, "ou=system", null, null, 1, 1, false, Filter.create(uBadFilterCreateToString).toString());
}

@RequestMapping
public void testUnboundBad10(@RequestParam String uBadFilterCreateToStringBuffer, LDAPConnection c) throws LDAPException {
StringBuilder b = new StringBuilder();
Filter.create(uBadFilterCreateToStringBuffer).toNormalizedString(b);
c.search(null, "ou=system", null, null, 1, 1, false, b.toString());
}


@RequestMapping
public void testUnboundBad11(@RequestParam String uBadSearchRequestDuplicate, LDAPConnection c)
throws LDAPException {
SearchRequest s = new SearchRequest(null, "ou=system", null, null, 1, 1, false,
"(uid=" + uBadSearchRequestDuplicate + ")");
c.search(s.duplicate());
}

@RequestMapping
public void testUnboundBad12(@RequestParam String uBadROSearchRequestDuplicate, LDAPConnection c)
throws LDAPException {
ReadOnlySearchRequest s = new SearchRequest(null, "ou=system", null, null, 1, 1, false,
"(uid=" + uBadROSearchRequestDuplicate + ")");
c.search(s.duplicate());
}

@RequestMapping
public void testUnboundBad13(@RequestParam String uBadSearchRequestSetDN, LDAPConnection c)
throws LDAPException {
SearchRequest s = new SearchRequest(null, "", null, null, 1, 1, false, "");
s.setBaseDN(uBadSearchRequestSetDN);
c.search(s);
}

@RequestMapping
public void testUnboundBad14(@RequestParam String uBadSearchRequestSetFilter, LDAPConnection c)
throws LDAPException {
SearchRequest s = new SearchRequest(null, "ou=system", null, null, 1, 1, false, "");
s.setFilter(uBadSearchRequestSetFilter);
c.search(s);
}

@RequestMapping
public void testUnboundOk1(@RequestParam String uOkEqualityFilter, LDAPConnection c) throws LDAPSearchException {
c.search(null, "ou=system", null, null, 1, 1, false, Filter.createEqualityFilter("uid", uOkEqualityFilter));
}

@RequestMapping
public void testUnboundOk2(@RequestParam String uOkVaragsAttr, LDAPConnection c) throws LDAPSearchException {
c.search("ou=system", null, null, 1, 1, false, "(uid=fixed)", "a" + uOkVaragsAttr);
}

@RequestMapping
public void testUnboundOk3(@RequestParam String uOkFilterSearchRequest, LDAPConnection c) throws LDAPException {
SearchRequest s = new SearchRequest(null, "ou=system", null, null, 1, 1, false,
Filter.createEqualityFilter("uid", uOkFilterSearchRequest));
c.search(s);
}

@RequestMapping
public void testUnboundOk4(@RequestParam String uOkSearchRequestVarargs, LDAPConnection c) throws LDAPException {
SearchRequest s = new SearchRequest("ou=system", null, "(uid=fixed)", "va1", "va2", "va3",
"a" + uOkSearchRequestVarargs);
c.search(s);
}

// Spring LDAP
@RequestMapping
public void testSpringBad1(@RequestParam String sBad, @RequestParam String sBadDN, LdapTemplate c) {
c.search("ou=system" + sBadDN, "(uid=" + sBad + ")", 1, false, null);
}

@RequestMapping
public void testSpringBad2(@RequestParam String sBad, @RequestParam String sBadDNLNBuilder, LdapTemplate c) {
c.authenticate(LdapNameBuilder.newInstance("ou=system" + sBadDNLNBuilder).build(), "(uid=" + sBad + ")", "pass");
}

@RequestMapping
public void testSpringBad3(@RequestParam String sBad, @RequestParam String sBadDNLNBuilderAdd, LdapTemplate c) {
c.searchForObject(LdapNameBuilder.newInstance().add("ou=system" + sBadDNLNBuilderAdd).build(), "(uid=" + sBad + ")", null);
}

@RequestMapping
public void testSpringBad4(@RequestParam String sBadLdapQuery, LdapTemplate c) {
c.findOne(LdapQueryBuilder.query().filter("(uid=" + sBadLdapQuery + ")"), null);
}

@RequestMapping
public void testSpringBad5(@RequestParam String sBadFilter, @RequestParam String sBadDNLdapUtils, LdapTemplate c) {
c.find(LdapUtils.newLdapName("ou=system" + sBadDNLdapUtils), new HardcodedFilter("(uid=" + sBadFilter + ")"), null, null);
}

@RequestMapping
public void testSpringBad6(@RequestParam String sBadLdapQuery, LdapTemplate c) {
c.searchForContext(LdapQueryBuilder.query().filter("(uid=" + sBadLdapQuery + ")"));
}

@RequestMapping
public void testSpringBad7(@RequestParam String sBadLdapQuery2, LdapTemplate c) {
LdapQuery q = LdapQueryBuilder.query().filter("(uid=" + sBadLdapQuery2 + ")");
c.searchForContext(q);
}

@RequestMapping
public void testSpringBad8(@RequestParam String sBadLdapQueryWithFilter, LdapTemplate c) {
c.searchForContext(LdapQueryBuilder.query().filter(new HardcodedFilter("(uid=" + sBadLdapQueryWithFilter + ")")));
}

@RequestMapping
public void testSpringBad9(@RequestParam String sBadLdapQueryWithFilter2, LdapTemplate c) {
org.springframework.ldap.filter.Filter f = new HardcodedFilter("(uid=" + sBadLdapQueryWithFilter2 + ")");
c.searchForContext(LdapQueryBuilder.query().filter(f));
}

@RequestMapping
public void testSpringBad10(@RequestParam String sBadLdapQueryBase, LdapTemplate c) {
c.find(LdapQueryBuilder.query().base(sBadLdapQueryBase).base(), null, null, null);
}

@RequestMapping
public void testSpringBad11(@RequestParam String sBadLdapQueryComplex, LdapTemplate c) {
c.searchForContext(LdapQueryBuilder.query().base(sBadLdapQueryComplex).where("uid").is("test"));
}

@RequestMapping
public void testSpringBad12(@RequestParam String sBadFilterToString, LdapTemplate c) {
c.search("", new HardcodedFilter("(uid=" + sBadFilterToString + ")").toString(), 1, false, null);
}

@RequestMapping
public void testSpringBad13(@RequestParam String sBadFilterEncode, LdapTemplate c) {
StringBuffer s = new StringBuffer();
new HardcodedFilter("(uid=" + sBadFilterEncode + ")").encode(s);
c.search("", s.toString(), 1, false, null);
}

@RequestMapping
public void testSpringOk1(@RequestParam String sOkLdapQuery, LdapTemplate c) {
c.find(LdapQueryBuilder.query().filter("(uid={0})", sOkLdapQuery), null);
}

@RequestMapping
public void testSpringOk2(@RequestParam String sOkFilter, @RequestParam String sOkDN, LdapTemplate c) {
c.find(LdapNameBuilder.newInstance().add("ou", sOkDN).build(), new EqualsFilter("uid", sOkFilter), null, null);
}

@RequestMapping
public void testSpringOk3(@RequestParam String sOkLdapQuery, @RequestParam String sOkPassword, LdapTemplate c) {
c.authenticate(LdapQueryBuilder.query().filter("(uid={0})", sOkLdapQuery), sOkPassword);
}

// Apache LDAP API
@RequestMapping
public void testApacheBad1(@RequestParam String aBad, @RequestParam String aBadDN, LdapConnection c)
throws LdapException {
c.search("ou=system" + aBadDN, "(uid=" + aBad + ")", null);
}

@RequestMapping
public void testApacheBad2(@RequestParam String aBad, @RequestParam String aBadDNObjToString, LdapNetworkConnection c)
throws LdapException {
c.search(new Dn("ou=system" + aBadDNObjToString).getName(), "(uid=" + aBad + ")", null);
}

@RequestMapping
public void testApacheBad3(@RequestParam String aBadSearchRequest, LdapConnection c)
throws LdapException {
org.apache.directory.api.ldap.model.message.SearchRequest s = new SearchRequestImpl();
s.setFilter("(uid=" + aBadSearchRequest + ")");
c.search(s);
}

@RequestMapping
public void testApacheBad4(@RequestParam String aBadSearchRequestImpl, @RequestParam String aBadDNObj, LdapConnection c)
throws LdapException {
SearchRequestImpl s = new SearchRequestImpl();
s.setBase(new Dn("ou=system" + aBadDNObj));
c.search(s);
}

@RequestMapping
public void testApacheBad5(@RequestParam String aBadDNSearchRequestGet, LdapConnection c)
throws LdapException {
org.apache.directory.api.ldap.model.message.SearchRequest s = new SearchRequestImpl();
s.setBase(new Dn("ou=system" + aBadDNSearchRequestGet));
c.search(s.getBase(), "(uid=test", null);
}

@RequestMapping
public void testApacheOk1(@RequestParam String aOk, LdapConnection c)
throws LdapException {
org.apache.directory.api.ldap.model.message.SearchRequest s = new SearchRequestImpl();
s.setFilter(new EqualityNode<String>("uid", aOk));
c.search(s);
}

@RequestMapping
public void testApacheOk2(@RequestParam String aOk, LdapConnection c)
throws LdapException {
SearchRequestImpl s = new SearchRequestImpl();
Expand All @@ -309,17 +363,20 @@ public void testApacheOk2(@RequestParam String aOk, LdapConnection c)
}

// ESAPI encoder sanitizer
@RequestMapping
public void testOk3(@RequestParam String okEncodeForLDAP, DirContext ctx) throws NamingException {
Encoder encoder = DefaultEncoder.getInstance();
ctx.search("ou=system", "(uid=" + encoder.encodeForLDAP(okEncodeForLDAP) + ")", new SearchControls());
}

// Spring LdapEncoder sanitizer
@RequestMapping
public void testOk4(@RequestParam String okFilterEncode, DirContext ctx) throws NamingException {
ctx.search("ou=system", "(uid=" + LdapEncoder.filterEncode(okFilterEncode) + ")", new SearchControls());
}

// UnboundID Filter.encodeValue sanitizer
@RequestMapping
public void testOk5(@RequestParam String okUnboundEncodeValue, DirContext ctx) throws NamingException {
ctx.search("ou=system", "(uid=" + Filter.encodeValue(okUnboundEncodeValue) + ")", new SearchControls());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.springframework.stereotype;

import java.lang.annotation.*;

@Target(value=ElementType.TYPE)
@Retention(value=RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.springframework.stereotype;

import java.lang.annotation.*;

@Target(value=ElementType.TYPE)
@Retention(value=RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.springframework.stereotype;

import java.lang.annotation.*;

@Target(value=ElementType.TYPE)
@Retention(value=RetentionPolicy.RUNTIME)
@Documented
public @interface Indexed { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.springframework.web.bind.annotation;

import java.lang.annotation.*;

@Target(value={ElementType.METHOD,ElementType.TYPE})
@Retention(value=RetentionPolicy.RUNTIME)
@Documented
public @interface RequestMapping { }