Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

filter password query parameter in access log #919

Merged
merged 12 commits into from
Nov 6, 2021
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package net.ripe.db.whois.api.httpserver;

import org.eclipse.jetty.server.Slf4jRequestLogWriter;

import java.io.IOException;
import java.util.regex.Pattern;

public class FilteredSlf4jRequestLogWriter extends Slf4jRequestLogWriter {
private final String keyToFilter;
// Replace value passed to apikey with "FILTERED" but leave the last 3 characters if its API keys
private static final Pattern ApiKeyPattern = Pattern.compile("(?<=(?i)(apikey=))(.+?(?=\\S{3}[&|\\s]))");
private static final Pattern PasswordPattern = Pattern.compile("(?<=(?i)(password=))([^&]*)");

public FilteredSlf4jRequestLogWriter(String keyToFilter) {
this.keyToFilter = keyToFilter;
}

@Override
public void write(String requestEntry) throws IOException {
String filtered;

if (keyToFilter != null && keyToFilter.equalsIgnoreCase("apikey")) {
filtered = ApiKeyPattern.matcher(requestEntry).replaceAll("FILTERED");
} else {
filtered = PasswordPattern.matcher(requestEntry).replaceAll("FILTERED");
}

super.write(filtered);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,6 @@ public void stop(final boolean force) {

// Log requests to org.eclipse.jetty.server.RequestLog
private RequestLog createRequestLog() {
return new CustomRequestLog(new Slf4jRequestLogWriter(), EXTENDED_RIPE_LOG_FORMAT);
return new CustomRequestLog(new FilteredSlf4jRequestLogWriter("password"), EXTENDED_RIPE_LOG_FORMAT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.io.IOException;
import java.nio.file.Files;

import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;

Expand Down Expand Up @@ -92,6 +93,69 @@ public void log_request_x_forwarded_for() throws Exception {
}


@Test
public void password_filtered() throws Exception {
RestTest.target(getPort(), "whois/test/person/TP1-TEST?password=some-api_key-123")
eshryane marked this conversation as resolved.
Show resolved Hide resolved
.request()
.get(WhoisResources.class);


String actual = fileToString(getRequestLogFilename());
assertThat(actual, containsString("GET /whois/test/person/TP1-TEST?password=FILTERED"));
assertThat(actual, not(containsString("some-api_key-123")));
}

@Test
public void multiple_password_filtered() throws Exception {
RestTest.target(getPort(), "whois/test/person/TP1-TEST?password=pass1&password=pass2")
.request()
.get(WhoisResources.class);


String actual = fileToString(getRequestLogFilename());
assertThat(actual, containsString("GET /whois/test/person/TP1-TEST?password=FILTERED&password=FILTERED"));
assertThat(actual, not(containsString("pass1")));
assertThat(actual, not(containsString("pass2")));
}

@Test
public void multiple_query_password_filtered() throws Exception {
RestTest.target(getPort(), "whois/test/person/TP1-TEST?password=pass1&key=value")
.request()
.get(WhoisResources.class);


String actual = fileToString(getRequestLogFilename());
assertThat(actual, containsString("GET /whois/test/person/TP1-TEST?password=FILTERED&key=value"));
assertThat(actual, containsString("key=value"));
assertThat(actual, not(containsString("pass1")));
}

@Test
public void multiple_query_password_last_filtered() throws Exception {
RestTest.target(getPort(), "whois/test/person/TP1-TEST?key=value&password=pass1")
.request()
.get(WhoisResources.class);


String actual = fileToString(getRequestLogFilename());
assertThat(actual, containsString("GET /whois/test/person/TP1-TEST?key=value&password=FILTERED"));
assertThat(actual, containsString("key=value"));
assertThat(actual, not(containsString("pass1")));
}

@Test
public void password_filtered_case_insensitive() throws Exception {
RestTest.target(getPort(), "whois/test/person/TP1-TEST?PassWord=pass1")
.request()
.get(WhoisResources.class);


String actual = fileToString(getRequestLogFilename());
assertThat(actual.toLowerCase(), containsString("password=FILTERED".toLowerCase()));
assertThat(actual, not(containsString("pass1")));
}

// helper methods

private static void cleanupRequestLogDirectory() throws IOException {
Expand Down