From 3383b0f376ddbfc348ecedc6fefc72adba929286 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Mon, 28 Nov 2016 16:40:02 +0100 Subject: [PATCH] SONAR-8423 Properly fail on invalid basic header --- .../authentication/BasicAuthenticator.java | 10 +++++++- .../BasicAuthenticatorTest.java | 25 +++++++++++++------ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/BasicAuthenticator.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/BasicAuthenticator.java index 9808d57b8f3..d87da6dcca4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/authentication/BasicAuthenticator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/authentication/BasicAuthenticator.java @@ -65,7 +65,7 @@ public class BasicAuthenticator { private static String[] getCredentials(String authorizationHeader) { String basicAuthEncoded = authorizationHeader.substring(6); - String basicAuthDecoded = new String(BASE64_DECODER.decode(basicAuthEncoded.getBytes(Charsets.UTF_8)), Charsets.UTF_8); + String basicAuthDecoded = getDecodedBasicAuth(basicAuthEncoded); int semiColonPos = basicAuthDecoded.indexOf(':'); if (semiColonPos <= 0) { @@ -76,6 +76,14 @@ public class BasicAuthenticator { return new String[] {login, password}; } + private static String getDecodedBasicAuth(String basicAuthEncoded) { + try { + return new String(BASE64_DECODER.decode(basicAuthEncoded.getBytes(Charsets.UTF_8)), Charsets.UTF_8); + } catch (Exception e) { + throw new UnauthorizedException("Invalid basic header"); + } + } + private UserDto authenticate(String login, String password, HttpServletRequest request) { if (isEmpty(password)) { return authenticateFromUserToken(login); diff --git a/server/sonar-server/src/test/java/org/sonar/server/authentication/BasicAuthenticatorTest.java b/server/sonar-server/src/test/java/org/sonar/server/authentication/BasicAuthenticatorTest.java index 692db7ea601..a5098b5a942 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/authentication/BasicAuthenticatorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/authentication/BasicAuthenticatorTest.java @@ -20,14 +20,6 @@ package org.sonar.server.authentication; -import static com.google.common.base.Charsets.UTF_8; -import static org.assertj.core.api.Java6Assertions.assertThat; -import static org.junit.rules.ExpectedException.none; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - import java.util.Base64; import java.util.Optional; import javax.servlet.http.HttpServletRequest; @@ -44,6 +36,14 @@ import org.sonar.db.user.UserTesting; import org.sonar.server.exceptions.UnauthorizedException; import org.sonar.server.usertoken.UserTokenAuthenticator; +import static com.google.common.base.Charsets.UTF_8; +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.junit.rules.ExpectedException.none; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + public class BasicAuthenticatorTest { private static final Base64.Encoder BASE64_ENCODER = Base64.getEncoder(); @@ -117,6 +117,15 @@ public class BasicAuthenticatorTest { underTest.authenticate(request); } + @Test + public void fail_to_authenticate_when_invalid_header() throws Exception { + when(request.getHeader("Authorization")).thenReturn("Basic Invàlid"); + + expectedException.expect(UnauthorizedException.class); + expectedException.expectMessage("Invalid basic header"); + underTest.authenticate(request); + } + @Test public void authenticate_from_user_token() throws Exception { insertUser(UserTesting.newUserDto().setLogin(LOGIN)); -- 2.39.5