diff options
4 files changed, 109 insertions, 31 deletions
diff --git a/docs/release-notes.rst b/docs/release-notes.rst index eb3878d..62d2c23 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -27,9 +27,13 @@ El Alto **Known Issues** - `LOG-1159 <https://jira.onap.org/browse/LOG-1159>`_ Vulnerability issue: logging-analytics version 5.0.9.RELEASE -**Security Notes** +**Known Security Issues** - - LOG code has been formally scanned during build time using NexusIQ and all Critical vulnerabilities have been addressed, items that remain open have been assessed for risk and determined to be false positive. The LOG open Critical security vulnerabilities and their risk assessment have been documented as part of the `project <https://wiki.onap.org/display/DW/El+Alto+Vulnerabilities>`_. + - `OJSI-200 <https://jira.onap.org/browse/OJSI-200>`_ Logging exposes unprotected APIs/UIs (CVE-2019-12125) + - `OJSI-155 <https://jira.onap.org/browse/OJSI-155>`_ LOG demo target exposes plain text HTTP endpoint using port 30398 + - `OJSI-125 <https://jira.onap.org/browse/OJSI-125>`_ log-es exposes plain text HTTP endpoint using port 30254 + - `OJSI-124 <https://jira.onap.org/browse/OJSI-124>`_ log-kibana exposes plain text HTTP endpoint using port 30253 + - `LOG-1114 <https://jira.onap.org/browse/LOG-1114>`_ Need for "ReadWriteMany" access on storage when deploying on Kubernetes? Quick Links: - `LOG project page <https://wiki.onap.org/display/DW/Logging+Enhancements+Project>`_ @@ -88,9 +92,17 @@ El Alto - `LOG-1118 <https://jira.onap.org/browse/LOG-1118>`_ Vulnerability issue: POMBA-SDNC-CONTEXT-BUILDER and POMBA-NETWORK-DISCOVERY-CONTEXT-BUILDER js-yaml - `LOG-1117 <https://jira.onap.org/browse/LOG-1117>`_ Vulnerability issue: POMBA-SDNC-CONTEXT-BUILDER and POMBA-NETWORK-DISCOVERY-CONTEXT-BUILDER uikit - `LOG-1160 <https://jira.onap.org/browse/LOG-1160>`_ Vulnerability issue: jackson-databind 2.9.9 - -**Security Notes** - - all nodeports for Kibana, context builders and data-router are open by default for now + - `LOG-1016 <https://jira.onap.org/browse/LOG-1016>`_ When comparing attributes from multiple sources, violations thrown do not accurately show the issue. + - `LOG-1017 <https://jira.onap.org/browse/LOG-1017>`_ Violations are thrown on attributes that are same (or missing) + - `LOG-1051 <https://jira.onap.org/browse/LOG-1051>`_ pomba-data-router do not start due to wrong AAi configuration (with Dublin release of the data router but works with the Casablanca version) + - `LOG-1084 <https://jira.onap.org/browse/LOG-1084>`_ Need authentication for pomba-kibana (node port = 30234) + - `LOG-1085 <https://jira.onap.org/browse/LOG-1085>`_ Need authentication for logging-elasticsearch (node port = 30254) + - `LOG-1086 <https://jira.onap.org/browse/LOG-1086>`_ Need authentication for logging-kibana (node port = 30253) + - `LOG-1114 <https://jira.onap.org/browse/LOG-1114>`_ Need for "ReadWriteMany" access on storage when deploying on Kubernetes? + +**Known Security Issues** + - `OJSI-123 <https://jira.onap.org/browse/OJSI-123>`_ pomba-data-router exposes plain text HTTP endpoint using port 30249 + - `OJSI-115 <https://jira.onap.org/browse/OJSI-115>`_ pomba-kibana exposes plain text HTTP endpoint using port 30234 POMBA code has been formally scanned during build time using NexusIQ and all Critical vulnerabilities have been addressed, items that remain open have been assessed for risk and determined to be false positive. The LOG open Critical security vulnerabilities and their risk assessment have been documented as part of the `project <https://wiki.onap.org/display/DW/El+Alto+Vulnerabilities>`_. diff --git a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/MDCSetup.java b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/MDCSetup.java index 93c16a8..c3391e9 100644 --- a/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/MDCSetup.java +++ b/reference/logging-filter/logging-filter-base/src/main/java/org/onap/logging/filter/base/MDCSetup.java @@ -26,6 +26,7 @@ import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; +import java.util.Base64; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.HttpHeaders; @@ -123,46 +124,75 @@ public class MDCSetup { } public void setMDCPartnerName(SimpleMap headers) { - logger.trace("Checking X-ONAP-PartnerName header for partnerName."); - String partnerName = headers.get(ONAPLogConstants.Headers.PARTNER_NAME); - if (partnerName == null || partnerName.isEmpty()) { - logger.trace("No valid X-ONAP-PartnerName header value. Checking User-Agent header for partnerName."); - partnerName = headers.get(HttpHeaders.USER_AGENT); - if (partnerName == null || partnerName.isEmpty()) { - logger.trace("No valid User-Agent header value. Checking X-ClientID header for partnerName."); - partnerName = headers.get(Constants.HttpHeaders.CLIENT_ID); - if (partnerName == null || partnerName.isEmpty()) { - logger.trace("No valid partnerName headers. Defaulting partnerName to UNKNOWN."); - partnerName = Constants.DefaultValues.UNKNOWN; - } - } - } + String partnerName = getMDCPartnerName(headers); MDC.put(ONAPLogConstants.MDCs.PARTNER_NAME, partnerName); } + protected String getMDCPartnerName(SimpleMap headers) { + String checkHeaderLogPattern = "Checking {} header to determine the value of {}"; + + logger.trace(checkHeaderLogPattern, HttpHeaders.AUTHORIZATION, ONAPLogConstants.MDCs.PARTNER_NAME); + String partnerName = getBasicAuthUserName(headers); + if (partnerName != null && !partnerName.isEmpty()) { + return partnerName; + } + + logger.trace(checkHeaderLogPattern, ONAPLogConstants.Headers.PARTNER_NAME, ONAPLogConstants.MDCs.PARTNER_NAME); + partnerName = headers.get(ONAPLogConstants.Headers.PARTNER_NAME); + if (partnerName != null && !partnerName.isEmpty()) { + return partnerName; + } + + logger.trace(checkHeaderLogPattern, HttpHeaders.USER_AGENT, ONAPLogConstants.MDCs.PARTNER_NAME); + partnerName = headers.get(HttpHeaders.USER_AGENT); + if (partnerName != null && !partnerName.isEmpty()) { + return partnerName; + } + + logger.trace(checkHeaderLogPattern, Constants.HttpHeaders.CLIENT_ID, ONAPLogConstants.MDCs.PARTNER_NAME); + partnerName = headers.get(Constants.HttpHeaders.CLIENT_ID); + if (partnerName != null && !partnerName.isEmpty()) { + return partnerName; + } + + logger.trace("{} value could not be determined, defaulting partnerName to {}.", + ONAPLogConstants.MDCs.PARTNER_NAME, Constants.DefaultValues.UNKNOWN); + return Constants.DefaultValues.UNKNOWN; + } + public void setLogTimestamp() { MDC.put(ONAPLogConstants.MDCs.LOG_TIMESTAMP, ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT)); } public void setElapsedTime() { - DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME; - ZonedDateTime entryTimestamp = - ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP), timeFormatter); - ZonedDateTime endTimestamp = ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.LOG_TIMESTAMP), timeFormatter); + try { + DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME; + ZonedDateTime entryTimestamp = + ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP), timeFormatter); + ZonedDateTime endTimestamp = + ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.LOG_TIMESTAMP), timeFormatter); - MDC.put(ONAPLogConstants.MDCs.ELAPSED_TIME, - Long.toString(ChronoUnit.MILLIS.between(entryTimestamp, endTimestamp))); + MDC.put(ONAPLogConstants.MDCs.ELAPSED_TIME, + Long.toString(ChronoUnit.MILLIS.between(entryTimestamp, endTimestamp))); + } catch (Exception e) { + logger.warn("Unable to calculate elapsed time due to error: {}", e.getMessage()); + } } public void setElapsedTimeInvokeTimestamp() { - DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME; - ZonedDateTime entryTimestamp = - ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP), timeFormatter); - ZonedDateTime endTimestamp = ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.LOG_TIMESTAMP), timeFormatter); + try { + DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME; + ZonedDateTime entryTimestamp = + ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP), timeFormatter); + ZonedDateTime endTimestamp = + ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.LOG_TIMESTAMP), timeFormatter); - MDC.put(ONAPLogConstants.MDCs.ELAPSED_TIME, - Long.toString(ChronoUnit.MILLIS.between(entryTimestamp, endTimestamp))); + MDC.put(ONAPLogConstants.MDCs.ELAPSED_TIME, + Long.toString(ChronoUnit.MILLIS.between(entryTimestamp, endTimestamp))); + } catch (Exception e) { + logger.warn("Unable to calculate elapsed time due to error: {}", e.getMessage()); + } } public void setResponseStatusCode(int code) { @@ -219,4 +249,21 @@ public class MDCSetup { } return propertyValue; } + + protected String getBasicAuthUserName(SimpleMap headers) { + String encodedAuthorizationValue = headers.get(HttpHeaders.AUTHORIZATION); + if (encodedAuthorizationValue != null) { + try { + // This will strip the word Basic and single space + encodedAuthorizationValue = encodedAuthorizationValue.substring(6); + byte[] decodedBytes = Base64.getDecoder().decode(encodedAuthorizationValue); + String decodedString = new String(decodedBytes); + int idx = decodedString.indexOf(':'); + return decodedString.substring(0, idx); + } catch (IllegalArgumentException e) { + logger.error("could not decode basic auth value " + encodedAuthorizationValue, e); + } + } + return null; + } } diff --git a/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/MDCSetupTest.java b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/MDCSetupTest.java index 31d8da6..22ab9c3 100644 --- a/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/MDCSetupTest.java +++ b/reference/logging-filter/logging-filter-base/src/test/java/org/onap/logging/filter/base/MDCSetupTest.java @@ -191,6 +191,18 @@ public class MDCSetupTest extends MDCSetup { } @Test + public void setMDCPartnerNameFromBasicAuth() { + MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>(); + String value = "Basic dXNlcjpwYXNz"; // decodes to user:pass + headerMap.putSingle(HttpHeaders.AUTHORIZATION, value); + SimpleMap headers = new SimpleJaxrsHeadersMap(headerMap); + + setMDCPartnerName(headers); + + assertEquals("user", MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME)); + } + + @Test public void setMDCPartnerNameTest() { MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<>(); headerMap.putSingle(ONAPLogConstants.Headers.PARTNER_NAME, "SO"); diff --git a/reference/logging-filter/logging-filter-base/src/test/resources/log4j2.properties b/reference/logging-filter/logging-filter-base/src/test/resources/log4j2.properties new file mode 100644 index 0000000..856bb26 --- /dev/null +++ b/reference/logging-filter/logging-filter-base/src/test/resources/log4j2.properties @@ -0,0 +1,7 @@ +appenders = console +appender.console.type = Console +appender.console.name = STDOUT + +rootLogger.level = TRACE +rootLogger.appenderRefs = stdout +rootLogger.appenderRef.stdout.ref = STDOUT
\ No newline at end of file |