Fix LDAP filter injection in Java and Spring Boot
=================================================

Build the filter with Spring LDAP's LdapQueryBuilder
(query().where("cn").is(name)), which puts every value through
LdapEncoder.filterEncode (RFC 4515), so * ( ) \ and NUL are matched as data,
not parsed as syntax. Keep the filter template constant.
LdapEncoder.nameEncode is DN escaping and does not neutralize a filter.

Page: https://softwaresecurity.com/fix/ldap-injection/java-spring/

What is in this archive
-----------------------
ldap-injection/java-spring/   the project: three implementations of the same code and one test suite
  src/main/java/com/example/directory/impl/VulnerableDirectorySearch.java   (vulnerable)
  src/main/java/com/example/directory/impl/FixedDirectorySearch.java   (fixed)
  src/main/java/com/example/directory/impl/WrongDirectorySearch.java   (a plausible fix that still fails)
run-all.mjs   runs the tests in all three modes and checks the results (Node.js only)
LICENSE-CODE.txt

Run it
------
  Tested with OpenJDK 21.0.12.1 (Homebrew), Maven 3.9.16. run-all.mjs needs
  Node.js 22 or later. Supported versions:
  https://softwaresecurity.com/fix/versions/

  From the ldap-injection/java-spring folder, install the dependencies once
  (this needs network access):

    mvn -B -q test

  Then run the tests. IMPL chooses the implementation the tests load:

    # every test passes
    IMPL=fixed mvn -B -o -q test
    # an exploit test fails
    IMPL=vulnerable mvn -B -o -q test
    # a test fails
    IMPL=wrong mvn -B -o -q test

  The JUnit report is written to target/surefire-reports/TEST-*.xml. To run all
  three modes and check the results in one step, run the harness from this top
  folder (it needs only Node.js; --install runs the install step first):

    node run-all.mjs --install ldap-injection/java-spring
    node run-all.mjs ldap-injection/java-spring

Verified
--------
  11 October 2026 on macOS 27.0 (Darwin 27.0.0, arm64), with jdk OpenJDK
  21.0.12.1, maven 3.9.16, springBoot 4.1.1, springFramework 7.0.9, springLdap
  4.1.1, unboundIdLdapSdk 7.0.5, tomcat 11.0.26, jackson 3.1.7, junitJupiter
  6.0.3, semgrep 1.180.0. Versions and results hold for that date: run the tests
  with your own versions before relying on the fix.

Licence
-------
  The code is MIT licensed (LICENSE-CODE.txt). The page text is CC BY 4.0.
