import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.joining;
import static org.apache.commons.lang.StringUtils.isBlank;
+import static org.sonar.process.ProcessProperties.AUTH_JWT_SECRET;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.CLUSTER_HOSTS;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_HOST;
switch (nodeType) {
case APPLICATION:
ensureNotH2(props);
- requireValue(props, "sonar.auth.jwtBase64Hs256Secret");
+ requireValue(props, AUTH_JWT_SECRET);
break;
case SEARCH:
requireValue(props, SEARCH_HOST);
public static final String WEB_JAVA_OPTS = "sonar.web.javaOpts";
public static final String WEB_JAVA_ADDITIONAL_OPTS = "sonar.web.javaAdditionalOpts";
public static final String WEB_PORT = "sonar.web.port";
+ public static final String AUTH_JWT_SECRET = "sonar.auth.jwtBase64Hs256Secret";
public static final String CE_JAVA_OPTS = "sonar.ce.javaOpts";
public static final String CE_JAVA_ADDITIONAL_OPTS = "sonar.ce.javaAdditionalOpts";
import static com.google.common.base.Preconditions.checkNotNull;
import static io.jsonwebtoken.impl.crypto.MacProvider.generateKey;
import static java.util.Objects.requireNonNull;
+import static org.sonar.process.ProcessProperties.AUTH_JWT_SECRET;
/**
* This class can be used to encode or decode a JWT token
@ServerSide
public class JwtSerializer implements Startable {
- private static final String SECRET_KEY_PROPERTY = "sonar.auth.jwtBase64Hs256Secret";
-
private static final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS256;
private final Configuration config;
@Override
public void start() {
- Optional<String> encodedKey = config.get(SECRET_KEY_PROPERTY);
+ Optional<String> encodedKey = config.get(AUTH_JWT_SECRET);
if (encodedKey.isPresent()) {
this.secretKey = decodeSecretKeyProperty(encodedKey.get());
} else {
import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
import static org.apache.commons.lang.StringUtils.abbreviate;
+import static org.apache.commons.lang.StringUtils.containsIgnoreCase;
+import static org.apache.commons.lang.StringUtils.endsWithIgnoreCase;
+import static org.sonar.process.ProcessProperties.AUTH_JWT_SECRET;
import static org.sonar.process.systeminfo.SystemInfoUtils.setAttribute;
@ServerSide
public class SettingsSection implements SystemInfoSection, Global {
- static final int MAX_VALUE_LENGTH = 500;
+ private static final int MAX_VALUE_LENGTH = 500;
+ private static final String PASSWORD_VALUE = "xxxxxxxx";
private final Settings settings;
public SettingsSection(Settings settings) {
PropertyDefinitions definitions = settings.getDefinitions();
for (Map.Entry<String, String> prop : settings.getProperties().entrySet()) {
String key = prop.getKey();
- PropertyDefinition def = definitions.get(key);
- if (def == null || def.type() != PropertyType.PASSWORD) {
- setAttribute(protobuf, key, abbreviate(prop.getValue(), MAX_VALUE_LENGTH));
- }
+ String value = obfuscateValue(definitions, key, prop.getValue());
+ setAttribute(protobuf, key, value);
}
return protobuf.build();
}
+
+ private static String obfuscateValue(PropertyDefinitions definitions, String key, String value) {
+ PropertyDefinition def = definitions.get(key);
+ if (def != null && def.type() == PropertyType.PASSWORD) {
+ return PASSWORD_VALUE;
+ }
+ if (endsWithIgnoreCase(key, ".secured") ||
+ containsIgnoreCase(key, "password") ||
+ containsIgnoreCase(key, "passcode") ||
+ AUTH_JWT_SECRET.equals(key)) {
+ return PASSWORD_VALUE;
+ }
+ return abbreviate(value, MAX_VALUE_LENGTH);
+ }
}
ProtobufSystemInfo.Section protobuf = underTest.toProtobuf();
String value = attribute(protobuf, "foo").getStringValue();
- assertThat(value).hasSize(SettingsSection.MAX_VALUE_LENGTH).startsWith("abcde");
+ assertThat(value).hasSize(500).startsWith("abcde");
}
@Test
- public void exclude_password_properties() {
- settings.setProperty(PASSWORD_PROPERTY, "abcde");
+ public void value_is_obfuscated_if_key_matches_patterns() {
+ verifyObfuscated(PASSWORD_PROPERTY);
+ verifyObfuscated("foo.password.something");
+ // case insensitive search of "password" term
+ verifyObfuscated("bar.CheckPassword");
+ verifyObfuscated("foo.passcode.something");
+ // case insensitive search of "passcode" term
+ verifyObfuscated("bar.CheckPassCode");
+ verifyObfuscated("foo.something.secured");
+ verifyObfuscated("bar.something.Secured");
+ verifyObfuscated("sonar.auth.jwtBase64Hs256Secret");
+ verifyNotObfuscated("securedStuff");
+ verifyNotObfuscated("foo");
+ }
+
+ private void verifyObfuscated(String key) {
+ settings.setProperty(key, "foo");
+ ProtobufSystemInfo.Section protobuf = underTest.toProtobuf();
+ assertThatAttributeIs(protobuf, key, "xxxxxxxx");
+ }
+
+ private void verifyNotObfuscated(String key) {
+ settings.setProperty(key, "foo");
ProtobufSystemInfo.Section protobuf = underTest.toProtobuf();
- assertThat(attribute(protobuf, PASSWORD_PROPERTY)).isNull();
+ assertThatAttributeIs(protobuf, key, "foo");
}
@Test
public void test_monitor_name() {
assertThat(underTest.toProtobuf().getName()).isEqualTo("Settings");
-
}
}