CVE-2023-33201 (published 2023-07-05T03:15Z)

Bouncy Castle For Java before 1.74 is affected by an LDAP injection vulnerability. The vulnerability only affects applications that use an LDAP CertStore from Bouncy Castle to validate X.509 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.

CVSS v3 base score: 5.3, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N)

Weakness information:
cwe_id: CWE-295
cwe_name: Improper Certificate Validation
description: The product does not validate, or incorrectly validates, a certificate.
extended_description: When a certificate is invalid or malicious, it might allow an attacker to spoof a trusted entity by interfering in the communication path between the host and client. The product might connect to a malicious host while believing it is a trusted host, or the product might be deceived into accepting spoofed data that appears to originate from a trusted host.
         

Fix information:
repo_url: https://github.com/bcgit/bc-java
commit_details: repo_url: https://github.com/bcgit/bc-java
author: royb
author_date: 2023-04-25 23:11:52-04:00
msg: added filter encode to search
repository: repo_url: https://github.com/bcgit/bc-java
repo_name: bcgit/bc-java
description: Bouncy Castle Java Distribution (Mirror)
repo_language: Java
owner: bcgit
file_changes: filename: X509LDAPCertStoreSpi.java
change_type: ModificationType.MODIFY
diff: @@ -375,6 +375,59 @@ public Collection engineGetCRLs(CRLSelector selector)
 
         return crlSet;
     }
+    private static String[] FILTER_ESCAPE_TABLE = new String['\\' + 1];
+
+
+    static {
+
+        // Filter encoding table -------------------------------------
+
+        // fill with char itself
+        for (char c = 0; c < FILTER_ESCAPE_TABLE.length; c++) {
+            FILTER_ESCAPE_TABLE[c] = String.valueOf(c);
+        }
+
+        // escapes (RFC2254)
+        FILTER_ESCAPE_TABLE['*'] = "\\2a";
+        FILTER_ESCAPE_TABLE['('] = "\\28";
+        FILTER_ESCAPE_TABLE[')'] = "\\29";
+        FILTER_ESCAPE_TABLE['\\'] = "\\5c";
+        FILTER_ESCAPE_TABLE[0] = "\\00";
+
+    }
+
+    /**
+     * Escape a value for use in a filter.
+     * @param value the value to escape.
+     * @return a properly escaped representation of the supplied value.
+     */
+    private String filterEncode(String value)
+    {
+        if (value == null)
+        {
+            return null;
+        }
+
+        // make buffer roomy
+        StringBuilder encodedValue = new StringBuilder(value.length() * 2);
+
+        int length = value.length();
+
+        for (int i = 0; i < length; i++) {
+
+            char c = value.charAt(i);
+
+            if (c < FILTER_ESCAPE_TABLE.length) {
+                encodedValue.append(FILTER_ESCAPE_TABLE[c]);
+            }
+            else {
+                // default: add the char
+                encodedValue.append(c);
+            }
+        }
+
+        return encodedValue.toString();
+    }
 
     /**
      * Returns a Set of byte arrays with the certificate or CRL encodings.
@@ -388,7 +441,8 @@ public Collection engineGetCRLs(CRLSelector selector)
     private Set search(String attributeName, String attributeValue,
                        String[] attrs) throws CertStoreException
     {
-        String filter = attributeName + "=" + attributeValue;
+        String filter = attributeName + "=" + filterEncode(attributeValue);
+        System.out.println(filter);
         if (attributeName == null)
         {
             filter = null;

programming_language: Java