From 7c4a1cdef5c4767aa0c6edfbb058ddbf2b0a358d Mon Sep 17 00:00:00 2001 From: James Baiera Date: Tue, 1 Jun 2021 16:46:03 -0400 Subject: [PATCH] Add X-Elastic-Product header on all http responses (#73434) * Add product response header to all responses * share header value privately across package * Make the product header lowercase. * Do not expose the product header if request is unauthenticated. * Fix checkstyle Co-authored-by: Elastic Machine --- .../src/main/java/org/elasticsearch/rest/RestController.java | 4 ++++ .../java/org/elasticsearch/rest/RestControllerTests.java | 5 +++++ .../xpack/security/rest/SecurityRestFilter.java | 5 ++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/rest/RestController.java b/server/src/main/java/org/elasticsearch/rest/RestController.java index 086f6b70f7cb4..e1bdbdc0b5c9e 100644 --- a/server/src/main/java/org/elasticsearch/rest/RestController.java +++ b/server/src/main/java/org/elasticsearch/rest/RestController.java @@ -57,6 +57,8 @@ public class RestController implements HttpServerTransport.Dispatcher { private static final Logger logger = LogManager.getLogger(RestController.class); private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(RestController.class); + static final String ELASTIC_PRODUCT_HTTP_HEADER = "X-elastic-product"; + static final String ELASTIC_PRODUCT_HTTP_HEADER_VALUE = "Elasticsearch"; private static final String ELASTIC_PRODUCT_ORIGIN_HTTP_HEADER = "X-elastic-product-origin"; private static final BytesReference FAVICON_RESPONSE; @@ -188,6 +190,7 @@ public void registerHandler(final RestHandler handler) { @Override public void dispatchRequest(RestRequest request, RestChannel channel, ThreadContext threadContext) { + threadContext.addResponseHeader(ELASTIC_PRODUCT_HTTP_HEADER, ELASTIC_PRODUCT_HTTP_HEADER_VALUE); try { tryAllHandlers(request, channel, threadContext); } catch (Exception e) { @@ -203,6 +206,7 @@ public void dispatchRequest(RestRequest request, RestChannel channel, ThreadCont @Override public void dispatchBadRequest(final RestChannel channel, final ThreadContext threadContext, final Throwable cause) { + threadContext.addResponseHeader(ELASTIC_PRODUCT_HTTP_HEADER, ELASTIC_PRODUCT_HTTP_HEADER_VALUE); try { final Exception e; if (cause == null) { diff --git a/server/src/test/java/org/elasticsearch/rest/RestControllerTests.java b/server/src/test/java/org/elasticsearch/rest/RestControllerTests.java index 65e600d41709a..262fd2704a454 100644 --- a/server/src/test/java/org/elasticsearch/rest/RestControllerTests.java +++ b/server/src/test/java/org/elasticsearch/rest/RestControllerTests.java @@ -40,6 +40,7 @@ import org.junit.Before; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -141,6 +142,10 @@ public MethodHandlers next() { assertEquals("true", threadContext.getHeader("header.1")); assertEquals("true", threadContext.getHeader("header.2")); assertNull(threadContext.getHeader("header.3")); + List expectedProductResponseHeader = new ArrayList<>(); + expectedProductResponseHeader.add(RestController.ELASTIC_PRODUCT_HTTP_HEADER_VALUE); + assertEquals(expectedProductResponseHeader, threadContext.getResponseHeaders() + .getOrDefault(RestController.ELASTIC_PRODUCT_HTTP_HEADER, null)); } public void testRequestWithDisallowedMultiValuedHeader() { diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/rest/SecurityRestFilter.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/rest/SecurityRestFilter.java index 6e4dccd2a69f6..64974c133f0ec 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/rest/SecurityRestFilter.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/rest/SecurityRestFilter.java @@ -111,7 +111,10 @@ private void handleException(String actionType, RestRequest request, RestChannel @Override public Map> filterHeaders(Map> headers) { if (headers.containsKey("Warning")) { - return Maps.copyMapWithRemovedEntry(headers, "Warning"); + headers = Maps.copyMapWithRemovedEntry(headers, "Warning"); + } + if (headers.containsKey("X-elastic-product")) { + headers = Maps.copyMapWithRemovedEntry(headers, "X-elastic-product"); } return headers; }