mirror of https://github.com/apache/lucene.git
SOLR-10076: Hide keystore and truststore passwords from /admin/info/* outputs.
This commit is contained in:
parent
bac3424936
commit
91c3f78f8f
|
@ -181,6 +181,8 @@ New Features
|
||||||
|
|
||||||
* SOLR-9045: Make RecoveryStrategy settings configurable. (Christine Poerschke)
|
* SOLR-9045: Make RecoveryStrategy settings configurable. (Christine Poerschke)
|
||||||
|
|
||||||
|
* SOLR-10076: Hide keystore and truststore passwords from /admin/info/* outputs. (Mano Kovacs via Mark Miller)
|
||||||
|
|
||||||
Bug Fixes
|
Bug Fixes
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,14 @@
|
||||||
package org.apache.solr.handler.admin;
|
package org.apache.solr.handler.admin;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
|
||||||
import org.apache.solr.common.util.NamedList;
|
import org.apache.solr.common.util.NamedList;
|
||||||
import org.apache.solr.common.util.SimpleOrderedMap;
|
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||||
import org.apache.solr.handler.RequestHandlerBase;
|
import org.apache.solr.handler.RequestHandlerBase;
|
||||||
import org.apache.solr.request.SolrQueryRequest;
|
import org.apache.solr.request.SolrQueryRequest;
|
||||||
import org.apache.solr.response.SolrQueryResponse;
|
import org.apache.solr.response.SolrQueryResponse;
|
||||||
|
import org.apache.solr.util.RedactionUtils;
|
||||||
|
|
||||||
import static org.apache.solr.common.params.CommonParams.NAME;
|
import static org.apache.solr.common.params.CommonParams.NAME;
|
||||||
|
|
||||||
|
@ -32,23 +34,36 @@ import static org.apache.solr.common.params.CommonParams.NAME;
|
||||||
*/
|
*/
|
||||||
public class PropertiesRequestHandler extends RequestHandlerBase
|
public class PropertiesRequestHandler extends RequestHandlerBase
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public static final String REDACT_STRING = RedactionUtils.getRedactString();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws IOException
|
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws IOException
|
||||||
{
|
{
|
||||||
Object props = null;
|
NamedList<String> props = new SimpleOrderedMap<>();
|
||||||
String name = req.getParams().get(NAME);
|
String name = req.getParams().get(NAME);
|
||||||
if( name != null ) {
|
if( name != null ) {
|
||||||
NamedList<String> p = new SimpleOrderedMap<>();
|
String property = getSecuredPropertyValue(name);
|
||||||
p.add( name, System.getProperty(name) );
|
props.add( name, property);
|
||||||
props = p;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
props = System.getProperties();
|
Enumeration<?> enumeration = System.getProperties().propertyNames();
|
||||||
|
while(enumeration.hasMoreElements()){
|
||||||
|
name = (String) enumeration.nextElement();
|
||||||
|
props.add(name, getSecuredPropertyValue(name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rsp.add( "system.properties", props );
|
rsp.add( "system.properties", props );
|
||||||
rsp.setHttpCaching(false);
|
rsp.setHttpCaching(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getSecuredPropertyValue(String name) {
|
||||||
|
if(RedactionUtils.isSystemPropertySensitive(name)){
|
||||||
|
return REDACT_STRING;
|
||||||
|
}
|
||||||
|
return System.getProperty(name);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////// SolrInfoMBeans methods //////////////////////
|
//////////////////////// SolrInfoMBeans methods //////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -36,6 +36,8 @@ import java.text.DecimalFormat;
|
||||||
import java.text.DecimalFormatSymbols;
|
import java.text.DecimalFormatSymbols;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
@ -50,7 +52,7 @@ import org.apache.solr.request.SolrQueryRequest;
|
||||||
import org.apache.solr.response.SolrQueryResponse;
|
import org.apache.solr.response.SolrQueryResponse;
|
||||||
import org.apache.solr.schema.IndexSchema;
|
import org.apache.solr.schema.IndexSchema;
|
||||||
import org.apache.solr.util.RTimer;
|
import org.apache.solr.util.RTimer;
|
||||||
|
import org.apache.solr.util.RedactionUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -66,6 +68,8 @@ public class SystemInfoHandler extends RequestHandlerBase
|
||||||
{
|
{
|
||||||
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||||
|
|
||||||
|
public static String REDACT_STRING = RedactionUtils.getRedactString();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Undocumented expert level system property to prevent doing a reverse lookup of our hostname.
|
* Undocumented expert level system property to prevent doing a reverse lookup of our hostname.
|
||||||
|
@ -373,7 +377,7 @@ public class SystemInfoHandler extends RequestHandlerBase
|
||||||
|
|
||||||
// the input arguments passed to the Java virtual machine
|
// the input arguments passed to the Java virtual machine
|
||||||
// which does not include the arguments to the main method.
|
// which does not include the arguments to the main method.
|
||||||
jmx.add( "commandLineArgs", mx.getInputArguments());
|
jmx.add( "commandLineArgs", getInputArgumentsRedacted(mx));
|
||||||
|
|
||||||
jmx.add( "startTime", new Date(mx.getStartTime()));
|
jmx.add( "startTime", new Date(mx.getStartTime()));
|
||||||
jmx.add( "upTimeMS", mx.getUptime() );
|
jmx.add( "upTimeMS", mx.getUptime() );
|
||||||
|
@ -437,6 +441,18 @@ public class SystemInfoHandler extends RequestHandlerBase
|
||||||
return newSizeAndUnits;
|
return newSizeAndUnits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<String> getInputArgumentsRedacted(RuntimeMXBean mx) {
|
||||||
|
List<String> list = new LinkedList<>();
|
||||||
|
for (String arg : mx.getInputArguments()) {
|
||||||
|
if (arg.startsWith("-D") && arg.contains("=") && RedactionUtils.isSystemPropertySensitive(arg.substring(2, arg.indexOf("=")))) {
|
||||||
|
list.add(String.format("%s=%s", arg.substring(0, arg.indexOf("=")), REDACT_STRING));
|
||||||
|
} else {
|
||||||
|
list.add(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class RedactionUtils {
|
||||||
|
public static final String SOLR_REDACTION_SYSTEM_PATTERN_PROP = "solr.redaction.system.pattern";
|
||||||
|
private static Pattern pattern = Pattern.compile(System.getProperty(SOLR_REDACTION_SYSTEM_PATTERN_PROP, ".*password.*"), Pattern.CASE_INSENSITIVE);
|
||||||
|
private static final String REDACT_STRING = "--REDACTED--";
|
||||||
|
|
||||||
|
private static boolean redactSystemProperty = Boolean.parseBoolean(System.getProperty("solr.redaction.system.enabled", "true"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if the given system property should be redacted.
|
||||||
|
*
|
||||||
|
* @param name The system property that is being checked.
|
||||||
|
* @return true if property should be redacted.
|
||||||
|
*/
|
||||||
|
static public boolean isSystemPropertySensitive(String name) {
|
||||||
|
return redactSystemProperty && pattern.matcher(name).matches();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return redaction string to be used instead of the value.
|
||||||
|
*/
|
||||||
|
static public String getRedactString() {
|
||||||
|
return REDACT_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setRedactSystemProperty(boolean redactSystemProperty) {
|
||||||
|
RedactionUtils.redactSystemProperty = redactSystemProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* 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.handler.admin;
|
||||||
|
|
||||||
|
import java.io.StringReader;
|
||||||
|
|
||||||
|
import org.apache.solr.SolrTestCaseJ4;
|
||||||
|
import org.apache.solr.client.solrj.impl.XMLResponseParser;
|
||||||
|
import org.apache.solr.common.params.CommonParams;
|
||||||
|
import org.apache.solr.common.util.NamedList;
|
||||||
|
import org.apache.solr.util.RedactionUtils;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
|
public class PropertiesRequestHandlerTest extends SolrTestCaseJ4 {
|
||||||
|
|
||||||
|
public static final String PASSWORD = "secret123";
|
||||||
|
public static final String REDACT_STRING = RedactionUtils.getRedactString();
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() throws Exception {
|
||||||
|
initCore("solrconfig.xml", "schema.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRedaction() throws Exception {
|
||||||
|
RedactionUtils.setRedactSystemProperty(true);
|
||||||
|
for(String propName: new String[]{"some.password", "javax.net.ssl.trustStorePassword"}){
|
||||||
|
System.setProperty(propName, PASSWORD);
|
||||||
|
NamedList<NamedList<NamedList<Object>>> properties = readProperties();
|
||||||
|
|
||||||
|
assertEquals("Failed to redact "+propName, REDACT_STRING, properties.get(propName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDisabledRedaction() throws Exception {
|
||||||
|
RedactionUtils.setRedactSystemProperty(false);
|
||||||
|
for(String propName: new String[]{"some.password", "javax.net.ssl.trustStorePassword"}){
|
||||||
|
System.setProperty(propName, PASSWORD);
|
||||||
|
NamedList<NamedList<NamedList<Object>>> properties = readProperties();
|
||||||
|
|
||||||
|
assertEquals("Failed to *not* redact "+propName, PASSWORD, properties.get(propName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private NamedList<NamedList<NamedList<Object>>> readProperties() throws Exception {
|
||||||
|
String xml = h.query(req(
|
||||||
|
CommonParams.QT, "/admin/properties",
|
||||||
|
CommonParams.WT, "xml"
|
||||||
|
));
|
||||||
|
|
||||||
|
XMLResponseParser parser = new XMLResponseParser();
|
||||||
|
return (NamedList<NamedList<NamedList<Object>>>)
|
||||||
|
parser.processResponse(new StringReader(xml)).get("system.properties");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue