You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by ge...@apache.org on 2022/10/11 16:54:49 UTC
[solr-sandbox] branch crossdc-wip updated: Redact properties before string-ifying or logging (#49)
This is an automated email from the ASF dual-hosted git repository.
gerlowskija pushed a commit to branch crossdc-wip
in repository https://gitbox.apache.org/repos/asf/solr-sandbox.git
The following commit(s) were added to refs/heads/crossdc-wip by this push:
new e246a24 Redact properties before string-ifying or logging (#49)
e246a24 is described below
commit e246a24e968593ff3d0aab746685dfce8c40388c
Author: Jason Gerlowski <ge...@apache.org>
AuthorDate: Tue Oct 11 12:54:44 2022 -0400
Redact properties before string-ifying or logging (#49)
Prior to this commit, certain log messages during Producer/Consumer
startup contained potentially sensitive information, such as SSL
passwords, etc.
This commit amends the string-ification of KafkaCrossDcConf and other
Map/Properties types to "redact" properties whose key/name contains a
block-list of values. This list currently consists of "password" and
"credentials": any property name containing these substrings (ignoring
case) will be redacted before logging.
---
.../solr/crossdc/common/KafkaCrossDcConf.java | 8 ++-
.../common/SensitivePropRedactionUtils.java | 66 ++++++++++++++++++++++
.../org/apache/solr/crossdc/consumer/Consumer.java | 4 +-
3 files changed, 75 insertions(+), 3 deletions(-)
diff --git a/crossdc-commons/src/main/java/org/apache/solr/crossdc/common/KafkaCrossDcConf.java b/crossdc-commons/src/main/java/org/apache/solr/crossdc/common/KafkaCrossDcConf.java
index 44c4e04..0b45bbb 100644
--- a/crossdc-commons/src/main/java/org/apache/solr/crossdc/common/KafkaCrossDcConf.java
+++ b/crossdc-commons/src/main/java/org/apache/solr/crossdc/common/KafkaCrossDcConf.java
@@ -23,6 +23,9 @@ import org.apache.kafka.common.config.internals.BrokerSecurityConfigs;
import java.util.*;
+import static org.apache.solr.crossdc.common.SensitivePropRedactionUtils.propertyRequiresRedaction;
+import static org.apache.solr.crossdc.common.SensitivePropRedactionUtils.redactPropertyIfNecessary;
+
public class KafkaCrossDcConf extends CrossDcConf {
public static final String DEFAULT_BATCH_SIZE_BYTES = "2097152";
@@ -245,7 +248,9 @@ public class KafkaCrossDcConf extends CrossDcConf {
StringBuilder sb = new StringBuilder(128);
for (ConfigProperty configProperty : CONFIG_PROPERTIES) {
if (properties.get(configProperty.getKey()) != null) {
- sb.append(configProperty.getKey()).append("=").append(properties.get(configProperty.getKey())).append(",");
+ final String printablePropertyValue = redactPropertyIfNecessary(configProperty.getKey(),
+ String.valueOf(properties.get(configProperty.getKey())));
+ sb.append(configProperty.getKey()).append("=").append(printablePropertyValue).append(",");
}
}
if (sb.length() > 0) {
@@ -254,5 +259,4 @@ public class KafkaCrossDcConf extends CrossDcConf {
return "KafkaCrossDcConf{" + sb + "}";
}
-
}
diff --git a/crossdc-commons/src/main/java/org/apache/solr/crossdc/common/SensitivePropRedactionUtils.java b/crossdc-commons/src/main/java/org/apache/solr/crossdc/common/SensitivePropRedactionUtils.java
new file mode 100644
index 0000000..58675a0
--- /dev/null
+++ b/crossdc-commons/src/main/java/org/apache/solr/crossdc/common/SensitivePropRedactionUtils.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.crossdc.common;
+
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Helper functionality related to redacting arbitrary properties which may contain sensitive password information.
+ *
+ * Used primarily as a safeguard before logging out configuration properties. Redaction logic heavily depends on string
+ * matching against elements of the {@link #PATTERNS_REQUIRING_REDACTION_LOWERCASE} block-list.
+ */
+public class SensitivePropRedactionUtils {
+ private static final String[] PATTERNS_REQUIRING_REDACTION_LOWERCASE = new String[] {"password", "credentials"};
+ private static final String REDACTED_STRING = "<REDACTED>";
+
+ public static boolean propertyRequiresRedaction(String propName) {
+ final String propNameLowercase = propName.toLowerCase(Locale.ROOT);
+ for (String pattern : PATTERNS_REQUIRING_REDACTION_LOWERCASE) {
+ if (propNameLowercase.contains(pattern)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Redacts a property value if necessary, and returns the result.
+ *
+ * Redaction only occurs when the property name matches a pattern on the
+ * {@link #PATTERNS_REQUIRING_REDACTION_LOWERCASE} block-list.
+ *
+ * @param propName the name or key of the property being considered for redaction
+ * @param propValue the value of the property under consideration; returned verbatim if redaction is not necessary.
+ */
+ public static String redactPropertyIfNecessary(String propName, String propValue) {
+ return propertyRequiresRedaction(propName) ? REDACTED_STRING : propValue;
+ }
+
+ public static String flattenAndRedactForLogging(Map<String, Object> properties) {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("{");
+ for (Map.Entry<String, Object> entry : properties.entrySet()) {
+ final Object printablePropValue = redactPropertyIfNecessary(entry.getKey(), String.valueOf(entry.getValue()));
+ sb.append(entry.getKey()).append("=").append(printablePropValue).append(", ");
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+}
diff --git a/crossdc-consumer/src/main/java/org/apache/solr/crossdc/consumer/Consumer.java b/crossdc-consumer/src/main/java/org/apache/solr/crossdc/consumer/Consumer.java
index 7a061f9..08749b0 100644
--- a/crossdc-consumer/src/main/java/org/apache/solr/crossdc/consumer/Consumer.java
+++ b/crossdc-consumer/src/main/java/org/apache/solr/crossdc/consumer/Consumer.java
@@ -21,6 +21,7 @@ import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.crossdc.common.ConfigProperty;
import org.apache.solr.crossdc.common.CrossDcConf;
import org.apache.solr.crossdc.common.KafkaCrossDcConf;
+import org.apache.solr.crossdc.common.SensitivePropRedactionUtils;
import org.apache.solr.crossdc.messageprocessor.SolrMessageProcessor;
import org.eclipse.jetty.server.Server;
import org.slf4j.Logger;
@@ -60,7 +61,8 @@ public class Consumer {
}
}
- log.info("Consumer startup config properties before adding additional properties from Zookeeper={}", properties);
+ log.info("Consumer startup config properties before adding additional properties from Zookeeper={}",
+ SensitivePropRedactionUtils.flattenAndRedactForLogging(properties));
String zkConnectString = (String) properties.get("zkConnectString");
if (zkConnectString == null) {