Test stacktraces for revealing any secret information

This commit is contained in:
Stefan Kalscheuer 2016-12-04 10:38:30 +01:00
parent ca51fed145
commit 3396693120

View File

@ -30,10 +30,7 @@ import org.junit.*;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestName; import org.junit.rules.TestName;
import java.io.BufferedWriter; import java.io.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Arrays; import java.util.Arrays;
@ -143,10 +140,13 @@ public class HTTPVaultConnectorTest {
@Test @Test
public void authTokenTest() { public void authTokenTest() {
TokenResponse res; TokenResponse res;
final String invalidToken = "52135869df23a5e64c5d33a9785af5edb456b8a4a235d1fe135e6fba1c35edf6";
try { try {
connector.authToken("52135869df23a5e64c5d33a9785af5edb456b8a4a235d1fe135e6fba1c35edf6"); connector.authToken(invalidToken);
fail("Logged in with invalid token"); fail("Logged in with invalid token");
} catch (VaultConnectorException ignored) { } catch (VaultConnectorException e) {
/* Assert that the exception does not reveal the token */
assertThat(stackTrace(e), not(stringContainsInOrder(invalidToken)));
} }
try { try {
@ -164,10 +164,15 @@ public class HTTPVaultConnectorTest {
@Test @Test
public void authUserPassTest() { public void authUserPassTest() {
AuthResponse res = null; AuthResponse res = null;
final String invalidUser = "foo";
final String invalidPass = "bar";
try { try {
connector.authUserPass("foo", "bar"); connector.authUserPass(invalidUser, invalidPass);
fail("Logged in with invalid credentials"); fail("Logged in with invalid credentials");
} catch (VaultConnectorException ignored) { } catch (VaultConnectorException e) {
/* Assert that the exception does not reveal credentials */
assertThat(stackTrace(e), not(stringContainsInOrder(invalidUser)));
assertThat(stackTrace(e), not(stringContainsInOrder(invalidPass)));
} }
try { try {
@ -232,19 +237,27 @@ public class HTTPVaultConnectorTest {
} }
/* Authenticate with valid secret ID against unknown role */ /* Authenticate with valid secret ID against unknown role */
final String invalidRole = "foo";
try { try {
AuthResponse res = connector.authAppRole("foo", APPROLE_SECRET); connector.authAppRole(invalidRole, APPROLE_SECRET);
fail("Successfully logged in with unknown role"); fail("Successfully logged in with unknown role");
} catch (VaultConnectorException e) { } catch (VaultConnectorException e) {
assertThat(e, is(instanceOf(InvalidResponseException.class))); assertThat(e, is(instanceOf(InvalidResponseException.class)));
/* Assert that the exception does not reveal role ID or secret */
assertThat(stackTrace(e), not(stringContainsInOrder(invalidRole)));
assertThat(stackTrace(e), not(stringContainsInOrder(APPROLE_SECRET)));
} }
/* Authenticate without wrong secret ID */ /* Authenticate without wrong secret ID */
final String invalidSecret = "foo";
try { try {
AuthResponse res = connector.authAppRole(APPROLE_ROLE, "foo"); AuthResponse res = connector.authAppRole(APPROLE_ROLE, "foo");
fail("Successfully logged in without secret ID"); fail("Successfully logged in without secret ID");
} catch (VaultConnectorException e) { } catch (VaultConnectorException e) {
assertThat(e, is(instanceOf(InvalidResponseException.class))); assertThat(e, is(instanceOf(InvalidResponseException.class)));
/* Assert that the exception does not reveal role ID or secret */
assertThat(stackTrace(e), not(stringContainsInOrder(APPROLE_ROLE)));
assertThat(stackTrace(e), not(stringContainsInOrder(invalidSecret)));
} }
/* Authenticate without secret ID */ /* Authenticate without secret ID */
@ -253,6 +266,8 @@ public class HTTPVaultConnectorTest {
fail("Successfully logged in without secret ID"); fail("Successfully logged in without secret ID");
} catch (VaultConnectorException e) { } catch (VaultConnectorException e) {
assertThat(e, is(instanceOf(InvalidResponseException.class))); assertThat(e, is(instanceOf(InvalidResponseException.class)));
/* Assert that the exception does not reveal role ID */
assertThat(stackTrace(e), not(stringContainsInOrder(APPROLE_ROLE)));
} }
/* Authenticate with secret ID on role with CIDR whitelist */ /* Authenticate with secret ID on role with CIDR whitelist */
@ -438,11 +453,17 @@ public class HTTPVaultConnectorTest {
/* Try to read path user has no permission to read */ /* Try to read path user has no permission to read */
SecretResponse res = null; SecretResponse res = null;
final String invalidPath = "invalid/path";
try { try {
res = connector.readSecret("invalid/path"); res = connector.readSecret(invalidPath);
fail("Invalid secret path successfully read."); fail("Invalid secret path successfully read.");
} catch (VaultConnectorException e) { } catch (VaultConnectorException e) {
assertThat(e, instanceOf(PermissionDeniedException.class)); assertThat(e, instanceOf(PermissionDeniedException.class));
/* Assert that the exception does not reveal secret or credentials */
assertThat(stackTrace(e), not(stringContainsInOrder(invalidPath)));
assertThat(stackTrace(e), not(stringContainsInOrder(USER_VALID)));
assertThat(stackTrace(e), not(stringContainsInOrder(PASS_VALID)));
assertThat(stackTrace(e), not(matchesPattern("[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}")));
} }
/* Try to read accessible path with known value */ /* Try to read accessible path with known value */
@ -748,7 +769,7 @@ public class HTTPVaultConnectorTest {
/* Write configuration file */ /* Write configuration file */
BufferedWriter bw = null; BufferedWriter bw = null;
File configFile = null; File configFile;
try { try {
configFile = tmpDir.newFile("vault.conf"); configFile = tmpDir.newFile("vault.conf");
bw = new BufferedWriter(new FileWriter(configFile)); bw = new BufferedWriter(new FileWriter(configFile));
@ -827,4 +848,16 @@ public class HTTPVaultConnectorTest {
} }
throw new IllegalStateException("Unable to find a free TCP port."); throw new IllegalStateException("Unable to find a free TCP port.");
} }
/**
* Retrieve StackTrace from throwable as string
*
* @param th the throwable
* @return the stack trace
*/
private static String stackTrace(final Throwable th) {
StringWriter sw = new StringWriter();
th.printStackTrace(new PrintWriter(sw, true));
return sw.getBuffer().toString();
}
} }