2022-09-19 14:54:20 +00:00
|
|
|
// Copyright 2022 Google LLC
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
//
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2022-06-15 15:48:21 +00:00
|
|
|
import com.code_intelligence.jazzer.api.FuzzedDataProvider;
|
|
|
|
import com.code_intelligence.jazzer.api.FuzzerSecurityIssueHigh;
|
|
|
|
import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
|
|
|
|
import org.springframework.security.ldap.SpringSecurityLdapTemplate;
|
|
|
|
import org.springframework.ldap.core.ContextSource;
|
|
|
|
import org.springframework.ldap.core.LdapTemplate;
|
|
|
|
import org.springframework.security.ldap.authentication.BindAuthenticator;
|
|
|
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
|
|
import org.springframework.security.core.SpringSecurityMessageSource;
|
|
|
|
import org.springframework.ldap.core.AuthenticationSource;
|
|
|
|
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
|
|
|
|
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
|
|
|
|
import com.unboundid.ldap.listener.InMemoryListenerConfig;
|
|
|
|
import com.unboundid.ldap.sdk.DN;
|
|
|
|
import com.unboundid.ldap.sdk.Entry;
|
|
|
|
import com.unboundid.ldap.sdk.LDAPException;
|
|
|
|
import com.unboundid.ldif.LDIFReader;
|
|
|
|
import org.springframework.security.ldap.server.UnboundIdContainer;
|
|
|
|
import org.springframework.ldap.core.DirContextOperations;
|
|
|
|
import org.springframework.security.authentication.BadCredentialsException;
|
|
|
|
|
|
|
|
public class BindAuthenticatorFuzzer {
|
|
|
|
private static InMemoryDirectoryServer directoryServer;
|
|
|
|
|
|
|
|
public static void fuzzerTearDown() {
|
|
|
|
if (directoryServer instanceof InMemoryDirectoryServer) {
|
|
|
|
directoryServer.shutDown(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void fuzzerTestOneInput(FuzzedDataProvider data) {
|
|
|
|
String username = data.consumeString(100);
|
|
|
|
String password = data.consumeRemainingAsString();
|
|
|
|
|
|
|
|
if (username.isEmpty() || password.isEmpty() || (username.equals("admin") && password.equals("secret"))) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (directoryServer instanceof InMemoryDirectoryServer) {
|
|
|
|
directoryServer.shutDown(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
createInMemoryLdapServer();
|
|
|
|
|
|
|
|
DefaultSpringSecurityContextSource context = new DefaultSpringSecurityContextSource("ldap://localhost:1234/dc=springframework,dc=org");
|
|
|
|
context.setUserDn("uid=admin,ou=system");
|
|
|
|
context.setPassword("secret");
|
|
|
|
context.afterPropertiesSet();
|
|
|
|
|
|
|
|
BindAuthenticator authenticator = new BindAuthenticator(context);
|
|
|
|
authenticator.setUserDnPatterns(new String[] { "uid={0},ou=people" });
|
|
|
|
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
|
|
|
|
DirContextOperations user = null;
|
|
|
|
|
|
|
|
try {
|
|
|
|
user = authenticator.authenticate(token);
|
|
|
|
} catch (BadCredentialsException e) {
|
|
|
|
// BadCredentialsException is expected here
|
|
|
|
} finally {
|
|
|
|
if (user != null) {
|
|
|
|
throw new FuzzerSecurityIssueHigh("Invalid user `" + username + "` could authenticate");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void createInMemoryLdapServer() {
|
|
|
|
String defaultPartitionName = "dc=springframework,dc=org";
|
|
|
|
try {
|
|
|
|
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(defaultPartitionName);
|
|
|
|
config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("LDAP", 1234));
|
|
|
|
config.setEnforceSingleStructuralObjectClass(false);
|
|
|
|
config.setEnforceAttributeSyntaxCompliance(true);
|
|
|
|
Entry dc = new Entry(new DN("dc=springframework,dc=org"));
|
|
|
|
dc.addAttribute("objectClass", "top", "domain", "extensibleObject");
|
|
|
|
dc.addAttribute("dc", "springframework");
|
|
|
|
dc.addAttribute("ou", "people");
|
|
|
|
|
|
|
|
Entry ou = new Entry(new DN("ou=people,dc=springframework,dc=org"));
|
|
|
|
ou.addAttribute("objectClass", "organizationalUnit");
|
|
|
|
ou.addAttribute("ou", "people");
|
|
|
|
|
|
|
|
Entry cn = new Entry(new DN("uid=admin,ou=people,dc=springframework,dc=org"));
|
|
|
|
cn.addAttribute("objectClass", "person");
|
|
|
|
cn.addAttribute("objectClass", "inetOrgPerson");
|
|
|
|
cn.addAttribute("cn", "Adm");
|
|
|
|
cn.addAttribute("sn", "In");
|
|
|
|
cn.addAttribute("uid", "admin");
|
|
|
|
cn.addAttribute("userPassword", "secret");
|
|
|
|
directoryServer = new InMemoryDirectoryServer(config);
|
|
|
|
|
|
|
|
directoryServer.add(dc);
|
|
|
|
directoryServer.add(ou);
|
|
|
|
directoryServer.add(cn);
|
|
|
|
directoryServer.startListening();
|
|
|
|
} catch (LDAPException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|