From b4e5875dd9def78e242a66fdf785270dbc8c90f2 Mon Sep 17 00:00:00 2001 From: Ruanhui <32773751+frostruan@users.noreply.github.com> Date: Wed, 24 Aug 2022 14:06:18 +0800 Subject: [PATCH] HBASE-27320 hide some sensitive configuration information in the UI (#4723) Co-authored-by: huiruan Signed-off-by: Tak Lon (Stephen) Wu Signed-off-by: Duo Zhang --- .../hadoop/hbase/http/conf/ConfServlet.java | 26 +++++++++++++++++-- .../hbase/http/conf/TestConfServlet.java | 9 +++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/conf/ConfServlet.java b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/conf/ConfServlet.java index 992b09191c4..27294b3e9ba 100644 --- a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/conf/ConfServlet.java +++ b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/conf/ConfServlet.java @@ -19,6 +19,8 @@ package org.apache.hadoop.hbase.http.conf; import java.io.IOException; import java.io.Writer; +import java.util.List; +import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -28,6 +30,8 @@ import org.apache.hadoop.hbase.http.HttpServer; import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceStability; +import org.apache.hbase.thirdparty.com.google.common.collect.ImmutableList; + /** * A servlet to print out the running configuration data. */ @@ -39,6 +43,9 @@ public class ConfServlet extends HttpServlet { private static final String FORMAT_JSON = "json"; private static final String FORMAT_XML = "xml"; private static final String FORMAT_PARAM = "format"; + private static final List MASK_PROPERTIES = + ImmutableList.of("password", "secret", "superuser"); + static final String MASKED = ""; /** * Return the Configuration of the daemon hosting this servlet. This is populated when the @@ -83,15 +90,30 @@ public class ConfServlet extends HttpServlet { */ static void writeResponse(Configuration conf, Writer out, String format) throws IOException, BadFormatException { + Configuration maskedConf = mask(conf); if (FORMAT_JSON.equals(format)) { - Configuration.dumpConfiguration(conf, out); + Configuration.dumpConfiguration(maskedConf, out); } else if (FORMAT_XML.equals(format)) { - conf.writeXml(out); + maskedConf.writeXml(out); } else { throw new BadFormatException("Bad format: " + format); } } + static Configuration mask(Configuration conf) { + Configuration maskedConf = new Configuration(conf); + for (Map.Entry entry : maskedConf) { + String key = entry.getKey(); + for (String maskProperty : MASK_PROPERTIES) { + if (key.toLowerCase().contains(maskProperty)) { + maskedConf.set(key, MASKED); + break; + } + } + } + return maskedConf; + } + public static class BadFormatException extends Exception { private static final long serialVersionUID = 1L; diff --git a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/conf/TestConfServlet.java b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/conf/TestConfServlet.java index 49f5af37f4f..fe202906e9c 100644 --- a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/conf/TestConfServlet.java +++ b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/conf/TestConfServlet.java @@ -113,6 +113,15 @@ public class TestConfServlet { assertTrue(foundSetting); } + @Test + public void testMask() { + final String passwordKey = "hbase.rpc.tls.keystore.password"; + Configuration conf = getTestConf(); + conf.set(passwordKey, "MyPassword"); + Configuration maskedConf = ConfServlet.mask(conf); + assertEquals(ConfServlet.MASKED, maskedConf.get(passwordKey)); + } + @Test public void testBadFormat() throws Exception { StringWriter sw = new StringWriter();