]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8416 prevent log flooding with über long login
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 28 Nov 2016 10:47:25 +0000 (11:47 +0100)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 14 Dec 2016 16:09:10 +0000 (17:09 +0100)
server/sonar-server/src/main/java/org/sonar/server/authentication/event/AuthenticationEventImpl.java
server/sonar-server/src/test/java/org/sonar/server/authentication/event/AuthenticationEventImplTest.java

index 413cbb99328b1b07a27229e05a99fd03fe59f17c..9cab0d0d95f8420dfa2b1d74e55655a020dda478 100644 (file)
@@ -29,13 +29,14 @@ import org.sonar.core.util.stream.Collectors;
 
 public class AuthenticationEventImpl implements AuthenticationEvent {
   private static final Logger LOGGER = Loggers.get("auth.event");
+  private static final int FLOOD_THRESHOLD = 128;
 
   @Override
   public void login(HttpServletRequest request, @Nullable String login, Source source) {
     LOGGER.info("login success [method|{}][provider|{}|{}][IP|{}|{}][login|{}]",
       source.getMethod(), source.getProvider(), source.getProviderName(),
       request.getRemoteAddr(), getAllIps(request),
-      emptyIfNull(login));
+      preventLogFlood(emptyIfNull(login)));
   }
 
   private static String getAllIps(HttpServletRequest request) {
@@ -49,11 +50,18 @@ public class AuthenticationEventImpl implements AuthenticationEvent {
       emptyIfNull(e.getMessage()),
       source.getMethod(), source.getProvider(), source.getProviderName(),
       request.getRemoteAddr(), getAllIps(request),
-      emptyIfNull(e.getLogin()));
+      preventLogFlood(emptyIfNull(e.getLogin())));
   }
 
   private static String emptyIfNull(@Nullable String login) {
     return login == null ? "" : login;
   }
 
+  private static String preventLogFlood(String str) {
+    if (str.length() > FLOOD_THRESHOLD) {
+      return str.substring(0, FLOOD_THRESHOLD) + "...(" + str.length() + ")";
+    }
+    return str;
+  }
+
 }
index f67c589c11ea7528431f2907e93e8500c9213097..b86235f2d08481c6f381b2a18bcd6bdbdb3eccc6 100644 (file)
@@ -40,6 +40,9 @@ import static org.sonar.server.authentication.event.AuthenticationEvent.Source;
 import static org.sonar.server.authentication.event.AuthenticationException.newBuilder;
 
 public class AuthenticationEventImplTest {
+  private static final String LOGIN_129_CHARS = "012345678901234567890123456789012345678901234567890123456789" +
+    "012345678901234567890123456789012345678901234567890123456789012345678";
+
   @Rule
   public LogTester logTester = new LogTester();
   @Rule
@@ -75,6 +78,14 @@ public class AuthenticationEventImplTest {
     verifyLog("login success [method|BASIC][provider|REALM|some provider name][IP||][login|foo]");
   }
 
+  @Test
+  public void login_prevents_log_flooding_on_login_starting_from_128_chars() {
+    underTest.login(mockRequest(), LOGIN_129_CHARS, Source.realm(Method.BASIC, "some provider name"));
+
+    verifyLog("login success [method|BASIC][provider|REALM|some provider name][IP||][login|012345678901234567890123456789012345678901234567890123456789" +
+      "01234567890123456789012345678901234567890123456789012345678901234567...(129)]");
+  }
+
   @Test
   public void login_logs_remote_ip_from_request() {
     underTest.login(mockRequest("1.2.3.4"), "foo", Source.realm(Method.EXTERNAL, "bar"));
@@ -131,22 +142,35 @@ public class AuthenticationEventImplTest {
   @Test
   public void failure_creates_INFO_log_with_method_provider_and_login() {
     AuthenticationException exception = newBuilder()
-        .setSource(Source.realm(Method.BASIC, "some provider name"))
-        .setMessage("something got terribly wrong")
-        .setLogin("BaR")
-        .build();
+      .setSource(Source.realm(Method.BASIC, "some provider name"))
+      .setMessage("something got terribly wrong")
+      .setLogin("BaR")
+      .build();
     underTest.failure(mockRequest(), exception);
 
     verifyLog("login failure [cause|something got terribly wrong][method|BASIC][provider|REALM|some provider name][IP||][login|BaR]");
   }
 
+  @Test
+  public void failure_prevents_log_flooding_on_login_starting_from_128_chars() {
+    AuthenticationException exception = newBuilder()
+      .setSource(Source.realm(Method.BASIC, "some provider name"))
+      .setMessage("pop")
+      .setLogin(LOGIN_129_CHARS)
+      .build();
+    underTest.failure(mockRequest(), exception);
+
+    verifyLog("login failure [cause|pop][method|BASIC][provider|REALM|some provider name][IP||][login|012345678901234567890123456789012345678901234567890123456789" +
+      "01234567890123456789012345678901234567890123456789012345678901234567...(129)]");
+  }
+
   @Test
   public void failure_logs_remote_ip_from_request() {
     AuthenticationException exception = newBuilder()
-        .setSource(Source.realm(Method.EXTERNAL, "bar"))
-        .setMessage("Damn it!")
-        .setLogin("Baaad")
-        .build();
+      .setSource(Source.realm(Method.EXTERNAL, "bar"))
+      .setMessage("Damn it!")
+      .setLogin("Baaad")
+      .build();
     underTest.failure(mockRequest("1.2.3.4"), exception);
 
     verifyLog("login failure [cause|Damn it!][method|EXTERNAL][provider|REALM|bar][IP|1.2.3.4|][login|Baaad]");
@@ -155,10 +179,10 @@ public class AuthenticationEventImplTest {
   @Test
   public void failure_logs_X_Forwarded_For_header_from_request() {
     AuthenticationException exception = newBuilder()
-        .setSource(Source.realm(Method.EXTERNAL, "bar"))
-        .setMessage("Hop la!")
-        .setLogin("foo")
-        .build();
+      .setSource(Source.realm(Method.EXTERNAL, "bar"))
+      .setMessage("Hop la!")
+      .setLogin("foo")
+      .build();
     HttpServletRequest request = mockRequest("1.2.3.4", asList("2.3.4.5"));
     underTest.failure(request, exception);
 
@@ -168,10 +192,10 @@ public class AuthenticationEventImplTest {
   @Test
   public void failure_logs_X_Forwarded_For_header_from_request_and_supports_multiple_headers() {
     AuthenticationException exception = newBuilder()
-        .setSource(Source.realm(Method.EXTERNAL, "bar"))
-        .setMessage("Boom!")
-        .setLogin("foo")
-        .build();
+      .setSource(Source.realm(Method.EXTERNAL, "bar"))
+      .setMessage("Boom!")
+      .setLogin("foo")
+      .build();
     HttpServletRequest request = mockRequest("1.2.3.4", asList("2.3.4.5", "6.5.4.3"), asList("9.5.6.7"), asList("6.3.2.4"));
     underTest.failure(request, exception);