From e77adba9aa0912a50ee6047992dd60506fc47bb5 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Mon, 2 Oct 2023 17:14:42 -0400 Subject: [PATCH] Skip decompression for WhoAmI and Health requests Signed-off-by: Craig Perkins --- .../security/filter/SecurityRestFilter.java | 8 ++++---- .../Netty4HttpRequestHeaderVerifier.java | 20 ++++++++++++------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java b/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java index effbe1d058..8d4a225b15 100644 --- a/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java +++ b/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java @@ -86,11 +86,11 @@ public class SecurityRestFilter { private WhitelistingSettings whitelistingSettings; private AllowlistingSettings allowlistingSettings; - private static final String HEALTH_SUFFIX = "health"; - private static final String WHO_AM_I_SUFFIX = "whoami"; + public static final String HEALTH_SUFFIX = "health"; + public static final String WHO_AM_I_SUFFIX = "whoami"; - private static final String REGEX_PATH_PREFIX = "/(" + LEGACY_OPENDISTRO_PREFIX + "|" + PLUGINS_PREFIX + ")/" + "(.*)"; - private static final Pattern PATTERN_PATH_PREFIX = Pattern.compile(REGEX_PATH_PREFIX); + public static final String REGEX_PATH_PREFIX = "/(" + LEGACY_OPENDISTRO_PREFIX + "|" + PLUGINS_PREFIX + ")/" + "(.*)"; + public static final Pattern PATTERN_PATH_PREFIX = Pattern.compile(REGEX_PATH_PREFIX); public SecurityRestFilter( final BackendRegistry registry, diff --git a/src/main/java/org/opensearch/security/ssl/http/netty/Netty4HttpRequestHeaderVerifier.java b/src/main/java/org/opensearch/security/ssl/http/netty/Netty4HttpRequestHeaderVerifier.java index 47a1e329f8..9770c3e83c 100644 --- a/src/main/java/org/opensearch/security/ssl/http/netty/Netty4HttpRequestHeaderVerifier.java +++ b/src/main/java/org/opensearch/security/ssl/http/netty/Netty4HttpRequestHeaderVerifier.java @@ -26,9 +26,14 @@ import org.opensearch.security.http.InterceptingRestChannel; import org.opensearch.threadpool.ThreadPool; +import java.util.regex.Matcher; + import static org.opensearch.http.netty4.Netty4HttpServerTransport.CONTEXT_TO_RESTORE; import static org.opensearch.http.netty4.Netty4HttpServerTransport.EARLY_RESPONSE; import static org.opensearch.http.netty4.Netty4HttpServerTransport.SHOULD_DECOMPRESS; +import static org.opensearch.security.filter.SecurityRestFilter.HEALTH_SUFFIX; +import static org.opensearch.security.filter.SecurityRestFilter.PATTERN_PATH_PREFIX; +import static org.opensearch.security.filter.SecurityRestFilter.WHO_AM_I_SUFFIX; public class Netty4HttpRequestHeaderVerifier extends SimpleChannelInboundHandler { private final SecurityRestFilter restFilter; @@ -52,11 +57,6 @@ public Netty4HttpRequestHeaderVerifier( public void channelRead0(ChannelHandlerContext ctx, DefaultHttpRequest msg) throws Exception { // DefaultHttpRequest should always be first and contain headers ReferenceCountUtil.retain(msg); - if (HttpMethod.OPTIONS.equals(msg.method())) { - // skip header verifier for pre-flight request. CORS Handler later in the pipeline will send early response - ctx.fireChannelRead(msg); - return; - } final Netty4HttpChannel httpChannel = ctx.channel().attr(Netty4HttpServerTransport.HTTP_CHANNEL_KEY).get(); final Netty4DefaultHttpRequest httpRequest = new Netty4DefaultHttpRequest(msg); @@ -68,14 +68,20 @@ public void channelRead0(ChannelHandlerContext ctx, DefaultHttpRequest msg) thro ); ThreadContext threadContext = threadPool.getThreadContext(); try (ThreadContext.StoredContext ignore = threadPool.getThreadContext().stashContext()) { - boolean isUnauthenticated = restFilter.checkAndAuthenticateRequest(restRequest, interceptingRestChannel, threadContext); + boolean isAuthenticated = !restFilter.checkAndAuthenticateRequest(restRequest, interceptingRestChannel, threadContext); ThreadContext.StoredContext contextToRestore = threadPool.getThreadContext().newStoredContext(false); ctx.channel().attr(EARLY_RESPONSE).set(interceptingRestChannel.getInterceptedResponse()); ctx.channel().attr(CONTEXT_TO_RESTORE).set(contextToRestore); - if (isUnauthenticated) { + Matcher matcher = PATTERN_PATH_PREFIX.matcher(restRequest.path()); + final String suffix = matcher.matches() ? matcher.group(2) : null; + if (!isAuthenticated + || HttpMethod.OPTIONS.equals(msg.method()) + || HEALTH_SUFFIX.equals(suffix) + || WHO_AM_I_SUFFIX.equals(suffix)) { + // skip header verifier for pre-flight request. CORS Handler later in the pipeline will send early response ctx.channel().attr(SHOULD_DECOMPRESS).set(Boolean.FALSE); } else { ctx.channel().attr(SHOULD_DECOMPRESS).set(Boolean.TRUE);