Do not echo back username on auth failure (#10097)

* Do not echo back username on auth failure

* use bad username

* Remove username from exception messages

* fix tests

* fix the tests

* hopefully this time

* this time the tests work

* fixed this time

* fix

* upgrade to Jetty 9.4.30

* Unknown users echo back Unauthorized

* fix
This commit is contained in:
Suneet Saldanha 2020-07-10 12:19:10 -07:00 committed by GitHub
parent b7f4ce70cc
commit 58f2e51161
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 34 additions and 16 deletions

View File

@ -48,7 +48,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.EnumSet;
import java.util.Locale;
import java.util.Map;
@JsonTypeName("basic")
@ -218,9 +217,7 @@ public class BasicHTTPAuthenticator implements Authenticator
}
catch (BasicSecurityAuthenticationException ex) {
LOG.info("Exception authenticating user %s - %s", user, ex.getMessage());
httpResp.sendError(HttpServletResponse.SC_UNAUTHORIZED,
String.format(Locale.getDefault(),
"User authentication failed username[%s].", user));
httpResp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "User authentication failed.");
}
}

View File

@ -165,7 +165,7 @@ public class LDAPCredentialsValidator implements CredentialsValidator
if (!validatePassword(this.ldapConfig, userDn, password)) {
LOG.debug("Password incorrect for LDAP user %s", username);
throw new BasicSecurityAuthenticationException("User LDAP authentication failed username[%s].", userDn.toString());
throw new BasicSecurityAuthenticationException("User LDAP authentication failed.");
}
byte[] salt = BasicAuthUtils.generateSalt();

View File

@ -83,7 +83,7 @@ public class MetadataStoreCredentialsValidator implements CredentialsValidator
return new AuthenticationResult(username, authorizerName, authenticatorName, null);
} else {
LOG.debug("Password incorrect for metadata store user %s", username);
throw new BasicSecurityAuthenticationException("User metadata store authentication failed username[%s].", username);
throw new BasicSecurityAuthenticationException("User metadata store authentication failed.");
}
}
}

View File

@ -174,7 +174,7 @@ public class BasicHTTPAuthenticatorTest
EasyMock.replay(req);
HttpServletResponse resp = EasyMock.createMock(HttpServletResponse.class);
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "User authentication failed username[userA].");
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "User authentication failed.");
EasyMock.expectLastCall().times(1);
EasyMock.replay(resp);
@ -210,7 +210,7 @@ public class BasicHTTPAuthenticatorTest
validator.validateCredentials(EasyMock.eq("basic"), EasyMock.eq("basic"), EasyMock.eq("userA"), EasyMock.aryEq("badpassword".toCharArray()))
)
.andThrow(
new BasicSecurityAuthenticationException("User authentication failed username[%s].", "userA")
new BasicSecurityAuthenticationException("User authentication failed.")
)
.times(1);
EasyMock.replay(validator);
@ -220,7 +220,7 @@ public class BasicHTTPAuthenticatorTest
EasyMock.replay(req);
HttpServletResponse resp = EasyMock.createMock(HttpServletResponse.class);
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "User authentication failed username[userA].");
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "User authentication failed.");
EasyMock.expectLastCall().times(1);
EasyMock.replay(resp);

View File

@ -143,7 +143,7 @@ public class DBCredentialsValidatorTest
String password = "badpassword";
expectedException.expect(BasicSecurityAuthenticationException.class);
expectedException.expectMessage("User metadata store authentication failed username[userA].");
expectedException.expectMessage("User metadata store authentication failed.");
validator.validateCredentials(authenticatorName, authorizerName, username, password.toCharArray());
}
}

View File

@ -291,8 +291,8 @@ public class ITBasicAuthConfigurationTest
datasourceOnlyUserClient,
SYS_SCHEMA_TASKS_QUERY,
adminTasks.stream()
.filter((taskEntry) -> "auth_test".equals(taskEntry.get("datasource")))
.collect(Collectors.toList())
.filter((taskEntry) -> "auth_test".equals(taskEntry.get("datasource")))
.collect(Collectors.toList())
);
// as user that can read auth_test and STATE
@ -317,7 +317,8 @@ public class ITBasicAuthConfigurationTest
datasourceWithStateUserClient,
SYS_SCHEMA_SERVER_SEGMENTS_QUERY,
adminServerSegments.stream()
.filter((serverSegmentEntry) -> ((String) serverSegmentEntry.get("segment_id")).contains("auth_test"))
.filter((serverSegmentEntry) -> ((String) serverSegmentEntry.get("segment_id")).contains(
"auth_test"))
.collect(Collectors.toList())
);
@ -326,8 +327,8 @@ public class ITBasicAuthConfigurationTest
datasourceWithStateUserClient,
SYS_SCHEMA_TASKS_QUERY,
adminTasks.stream()
.filter((taskEntry) -> "auth_test".equals(taskEntry.get("datasource")))
.collect(Collectors.toList())
.filter((taskEntry) -> "auth_test".equals(taskEntry.get("datasource")))
.collect(Collectors.toList())
);
// as user that can only read STATE
@ -471,6 +472,26 @@ public class ITBasicAuthConfigurationTest
testOptionsRequests(adminClient);
}
@Test
public void testMaliciousUser()
{
String maliciousUsername = "<script>alert('hello')</script>";
HttpClient maliciousClient = new CredentialedHttpClient(
new BasicCredentials(maliciousUsername, "noPass"),
httpClient
);
StatusResponseHolder responseHolder = HttpUtil.makeRequestWithExpectedStatus(
maliciousClient,
HttpMethod.GET,
config.getBrokerUrl() + "/status",
null,
HttpResponseStatus.UNAUTHORIZED
);
String responseContent = responseHolder.getContent();
Assert.assertTrue(responseContent.contains("<tr><th>MESSAGE:</th><td>Unauthorized</td></tr>"));
Assert.assertFalse(responseContent.contains(maliciousUsername));
}
private void testOptionsRequests(HttpClient httpClient)
{
HttpUtil.makeRequest(httpClient, HttpMethod.OPTIONS, config.getCoordinatorUrl() + "/status", null);
@ -522,7 +543,7 @@ public class ITBasicAuthConfigurationTest
catch (AvaticaSqlException ase) {
Assert.assertEquals(
ase.getErrorMessage(),
"Error while executing SQL \"SELECT * FROM INFORMATION_SCHEMA.COLUMNS\": Remote driver error: BasicSecurityAuthenticationException: User metadata store authentication failed username[admin]."
"Error while executing SQL \"SELECT * FROM INFORMATION_SCHEMA.COLUMNS\": Remote driver error: BasicSecurityAuthenticationException: User metadata store authentication failed."
);
return;
}