skip to content
Back to
Home Research Advisories CodeQL Wall of Fame Get Involved Events
June 27, 2023

GHSL-2023-045: LDAP injection in Bounty Castle For Java - CVE-2023-33201

Michael Stepankin

Coordinated Disclosure Timeline


Bouncy Castle For Java is affected by an LDAP injection vulnerability. The vulnerability only affects applications that use an LDAP CertStore from Bouncy Castle to validate X509 certificates. During the certificate validation process, Bouncy Castle inserts the certificate’s Subject Name into an LDAP search filter without any escaping, which leads to an LDAP injection vulnerability.


Bouncy Castle For Java

Tested Version



LDAP Injection in (GHSL-2023-045,CVE-2023-33201)

Bouncy Castle provides an API for validating X509 security certificates. During validation, Bouncy Castle should know where to locate root and intermediate trusted certificates. One of the options for developers is to use an LDAP directory for storing trusted certificates and their revocation lists. Bouncy castle provides this ability via X509LDAPCertStoreSpi and X509LDAPCertStoreParameters classes. For example, LDAP server at “ldap://” can be used in the following way:

X509LDAPCertStoreParameters CertStoreParameters = new X509LDAPCertStoreParameters.Builder("ldap://", "CN=certificates").build();
CertStore certStore = CertStore.getInstance("LDAP", CertStoreParameters, "BC");

In this scenario, Bouncy Castle makes requests to the configured LDAP store when a certificate is checked. The problem exists in the way Bouncy Castle constructs LDAP filters for these queries. Specifically, it takes the subject name from the certificate and includes it in the filter using string concatenation without any escaping.

 private Set search(String attributeName, String attributeValue,
                       String[] attrs) throws CertStoreException
      String filter = attributeName + "=" + attributeValue;
      if (attributeName == null)
          filter = null;
      DirContext ctx = null;
      Set set = new HashSet();

          ctx = connectLDAP();

          SearchControls constraints = new SearchControls();
          for (int i = 0; i < attrs.length; i++)
              String temp[] = new String[1];
              temp[0] = attrs[i];

              String filter2 = "(&(" + filter + ")(" + temp[0] + "=*))";

The query happens before the signature validation, so it can be exploited via untrusted self-signed certificate.


This issue may lead to Information Disclosure. A potential attacker can generate a self-signed certificate with a subject name that contains special characters, e.g: CN=Subject*)(objectclass=. This will be included into the filter and provides the attacker ability to specify additional attributes in the search query. This can be exploited as a blind LDAP injection: an attacker can enumerate valid attribute values using the boolean blind injection technique. The exploitation depends on the structure of the target LDAP directory, as well as what kind of errors are exposed to the user.

Steps to reproduce

Here is the java code snippet that demonstrates this vulnerability. To compile it, you need to place Bouncy castle libraries bcpkix-jdk15on-1.70.jar, bcprov-jdk15on-1.70.jar, bcutil-jdk15on-1.70.jar and unboundid-ldapsdk-6.0.7.jar into the lib directory. Then, you can compile it and execute using the following command:

javac -cp "./lib/*"
java -cp "./lib/*:./" BcInjection

The expected output should be like:

Starting LDAP server on
Generating self-signed certificate with subject:CN=Subject*)(objectclass=
Received LDAP search base:CN=certificates filter:(&(cn=*Subject*)(objectclass=*)(userCertificate=*))
Requested attributes:[userCertificate]


This issue was discovered and reported by GHSL team member @artsploit (Michael Stepankin).


You can contact the GHSL team at, please include a reference to GHSL-2023-045 in any communication regarding this issue.