From 803d4171bf24e82612c526d65de77aa580c8a62f Mon Sep 17 00:00:00 2001 From: Florian Zschocke Date: Sat, 4 Apr 2020 19:43:35 +0200 Subject: Delete password from memory in AuthenticationManager Zero out the password to remove it from memory after use. This is only a first step, implementing it for one method: `AuthenticationManager.authenticate(String, char[], String)`. --- .../com/gitblit/manager/AuthenticationManager.java | 42 ++++++++++++---------- src/main/java/com/gitblit/utils/StringUtils.java | 15 ++++++++ 2 files changed, 38 insertions(+), 19 deletions(-) (limited to 'src/main/java/com/gitblit') diff --git a/src/main/java/com/gitblit/manager/AuthenticationManager.java b/src/main/java/com/gitblit/manager/AuthenticationManager.java index 4f3f4f85..68c83dae 100644 --- a/src/main/java/com/gitblit/manager/AuthenticationManager.java +++ b/src/main/java/com/gitblit/manager/AuthenticationManager.java @@ -452,7 +452,6 @@ public class AuthenticationManager implements IAuthenticationManager { /** * Authenticate a user based on a username and password. * - * @see IUserService.authenticate(String, char[]) * @param username * @param password * @return a user object or null @@ -471,34 +470,39 @@ public class AuthenticationManager implements IAuthenticationManager { } String usernameDecoded = StringUtils.decodeUsername(username); - String pw = new String(password); - if (StringUtils.isEmpty(pw)) { + if (StringUtils.isEmpty(password)) { // can not authenticate empty password return null; } UserModel user = userManager.getUserModel(usernameDecoded); - // try local authentication - if (user != null && user.isLocalAccount()) { - UserModel returnedUser = authenticateLocal(user, password); - if (returnedUser != null) { - // user authenticated - return returnedUser; - } - } else { - // try registered external authentication providers - for (AuthenticationProvider provider : authenticationProviders) { - if (provider instanceof UsernamePasswordAuthenticationProvider) { - UserModel returnedUser = provider.authenticate(usernameDecoded, password); - if (returnedUser != null) { - // user authenticated - returnedUser.accountType = provider.getAccountType(); - return validateAuthentication(returnedUser, AuthenticationType.CREDENTIALS); + try { + // try local authentication + if (user != null && user.isLocalAccount()) { + UserModel returnedUser = authenticateLocal(user, password); + if (returnedUser != null) { + // user authenticated + return returnedUser; + } + } else { + // try registered external authentication providers + for (AuthenticationProvider provider : authenticationProviders) { + if (provider instanceof UsernamePasswordAuthenticationProvider) { + UserModel returnedUser = provider.authenticate(usernameDecoded, password); + if (returnedUser != null) { + // user authenticated + returnedUser.accountType = provider.getAccountType(); + return validateAuthentication(returnedUser, AuthenticationType.CREDENTIALS); + } } } } } + finally { + // Zero out password array to delete password from memory + Arrays.fill(password, Character.MIN_VALUE); + } // could not authenticate locally or with a provider logger.warn(MessageFormat.format("Failed login attempt for {0}, invalid credentials from {1}", username, diff --git a/src/main/java/com/gitblit/utils/StringUtils.java b/src/main/java/com/gitblit/utils/StringUtils.java index b192c80b..442acbbf 100644 --- a/src/main/java/com/gitblit/utils/StringUtils.java +++ b/src/main/java/com/gitblit/utils/StringUtils.java @@ -56,6 +56,21 @@ public class StringUtils { return value == null || value.trim().length() == 0; } + /** + * Returns true if the character array represents an empty String. + * An empty character sequence is defined as a sequence that + * either has no characters at all, or no characters above + * '\u0020' (space). + * + * @param value + * @return true if value is null or represents an empty String + */ + public static boolean isEmpty(char[] value) { + if (value == null || value.length == 0) return true; + for ( char c : value) if (c > '\u0020') return false; + return true; + } + /** * Replaces carriage returns and line feeds with html line breaks. * -- cgit v1.2.3