Skip to content

Commit c84a2e1

Browse files
committed
[BugFix] Prevent LDAP Injection in authentication
1 parent 53460c5 commit c84a2e1

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

fe/fe-core/src/main/java/com/starrocks/mysql/security/LdapSecurity.java

+17-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ public static boolean checkPasswordByRoot(String user, String password) {
9797
ctx = new InitialDirContext(env);
9898
SearchControls sc = new SearchControls();
9999
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
100-
String searchFilter = "(" + Config.authentication_ldap_simple_user_search_attr + "=" + user + ")";
100+
// Escapes special characters in user input to prevent LDAP injection
101+
String safeUser = escapeLdapValue(user);
102+
String searchFilter = "(" + Config.authentication_ldap_simple_user_search_attr + "=" + safeUser + ")";
101103
NamingEnumeration<SearchResult> results = ctx.search(baseDN, searchFilter, sc);
102104

103105
String userDN = null;
@@ -149,4 +151,18 @@ private static String trim(String src, String target) {
149151
}
150152
return src;
151153
}
154+
155+
public static String escapeLdapValue(String value) {
156+
if (value == null) {
157+
return null;
158+
}
159+
160+
value = value.replace("\\", "\\5c");
161+
value = value.replace("*", "\\2a");
162+
value = value.replace("(", "\\28");
163+
value = value.replace(")", "\\29");
164+
value = value.replace("|", "\\7c");
165+
value = value.replace("\\u0000", "\\00");
166+
return value;
167+
}
152168
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2021-present StarRocks, Inc. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.starrocks.mysql.privilege;
16+
17+
import com.starrocks.mysql.security.LdapSecurity;
18+
import org.junit.Assert;
19+
import org.junit.Test;
20+
21+
22+
public class LdapSecurityTest {
23+
24+
public LdapSecurity ldapSecurity;
25+
26+
@Test
27+
public void testEscapeJava() {
28+
String input = "admin)(|(uid=*";
29+
String escaped = ldapSecurity.escapeLdapValue(input);
30+
Assert.assertFalse(escaped.contains(")"));
31+
Assert.assertFalse(escaped.contains("("));
32+
Assert.assertFalse(escaped.contains("|"));
33+
Assert.assertFalse(escaped.contains("*"));
34+
Assert.assertFalse(escaped.contains("."));
35+
}
36+
37+
@Test
38+
public void testEscapeJava_NullInput() {
39+
String input = null;
40+
String escaped = ldapSecurity.escapeLdapValue(input);
41+
Assert.assertNull(escaped);
42+
}
43+
44+
@Test
45+
public void testEscapeJava_EmptyString() {
46+
String input = "";
47+
String escaped = ldapSecurity.escapeLdapValue(input);
48+
Assert.assertEquals("", escaped);
49+
}
50+
51+
@Test
52+
public void testEscapeJava_SpecialCharacters() {
53+
String input = "cn=admin,dc=example,dc=com";
54+
String escaped = ldapSecurity.escapeLdapValue(input);
55+
Assert.assertEquals(input, escaped);
56+
}
57+
}

0 commit comments

Comments
 (0)