This is an automated email from the ASF dual-hosted git repository.

orudyy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-broker-j.git

commit 69f8aaa353bec0a57d7b4b149a9552831f35d3c7
Author: Alex Rudyy <oru...@apache.org>
AuthorDate: Sun Jul 25 17:04:28 2021 +0100

    QPID-8552: [Broker-J] Respond with forbidden error when request is made 
using unsupported method
---
 .../server/management/plugin/HttpManagement.java   |  4 +-
 .../plugin/filter/ForbiddingTraceFilter.java       | 68 ----------------
 .../management/plugin/filter/MethodFilter.java     | 81 +++++++++++++++++++
 .../management/plugin/filter/MethodFilterTest.java | 92 ++++++++++++++++++++++
 4 files changed, 175 insertions(+), 70 deletions(-)

diff --git 
a/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
 
b/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
index 239d269..dcc58f1 100644
--- 
a/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
+++ 
b/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
@@ -83,9 +83,9 @@ import 
org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
 import org.apache.qpid.server.logging.messages.PortMessages;
 import 
org.apache.qpid.server.management.plugin.filter.AuthenticationCheckFilter;
 import org.apache.qpid.server.management.plugin.filter.ExceptionHandlingFilter;
-import org.apache.qpid.server.management.plugin.filter.ForbiddingTraceFilter;
 import 
org.apache.qpid.server.management.plugin.filter.InteractiveAuthenticationFilter;
 import org.apache.qpid.server.management.plugin.filter.LoggingFilter;
+import org.apache.qpid.server.management.plugin.filter.MethodFilter;
 import org.apache.qpid.server.management.plugin.filter.RedirectFilter;
 import 
org.apache.qpid.server.management.plugin.filter.RewriteRequestForUncompressedJavascript;
 import org.apache.qpid.server.management.plugin.servlet.FileServlet;
@@ -348,7 +348,7 @@ public class HttpManagement extends 
AbstractPluginAdapter<HttpManagement> implem
         corsFilter.setInitParameter(CrossOriginFilter.ALLOW_CREDENTIALS_PARAM, 
String.valueOf(getCorsAllowCredentials()));
         root.addFilter(corsFilter, "/*", EnumSet.of(DispatcherType.REQUEST));
 
-        root.addFilter(new FilterHolder(new ForbiddingTraceFilter()), "/*", 
EnumSet.of(DispatcherType.REQUEST));
+        root.addFilter(new FilterHolder(new MethodFilter()), "/*", 
EnumSet.of(DispatcherType.REQUEST));
 
         addFiltersAndServletsForRest(root);
         if (!Boolean.TRUE.equals(getContextValue(Boolean.class, 
DISABLE_UI_CONTEXT_NAME)))
diff --git 
a/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/filter/ForbiddingTraceFilter.java
 
b/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/filter/ForbiddingTraceFilter.java
deleted file mode 100644
index c35b0df..0000000
--- 
a/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/filter/ForbiddingTraceFilter.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- *
- * 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.qpid.server.management.plugin.filter;
-
-import java.io.IOException;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * 
- * This {@link Filter} blocks HTTP TRACE commands from being
- * processed. All TRACE requests are sent a 403 error.
- * 
- */
-public class ForbiddingTraceFilter implements Filter
-{
-    private static final String METHOD_TRACE = "TRACE";
-
-    @Override
-    public void destroy()
-    {
-    }
-
-    @Override
-    public void init(FilterConfig config) throws ServletException
-    {
-    }
-
-    @Override
-    public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain) throws IOException,
-            ServletException
-    {
-        HttpServletRequest httpRequest = (HttpServletRequest) request;
-        HttpServletResponse httpResponse = (HttpServletResponse) response;
-        if (httpRequest.getMethod().equals(METHOD_TRACE))
-        {
-                httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
-                return;
-        }
-        chain.doFilter(request, response);
-    }
-
-}
diff --git 
a/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/filter/MethodFilter.java
 
b/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/filter/MethodFilter.java
new file mode 100644
index 0000000..8e8c577
--- /dev/null
+++ 
b/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/filter/MethodFilter.java
@@ -0,0 +1,81 @@
+/*
+ *
+ * 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.qpid.server.management.plugin.filter;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.qpid.server.management.plugin.HttpManagementConfiguration;
+import org.apache.qpid.server.management.plugin.HttpManagementUtil;
+
+public class MethodFilter implements Filter
+{
+    private static final Set<String> REST_API_METHODS = new 
HashSet<>(Arrays.asList("GET", "POST", "PUT", "DELETE"));
+    private HttpManagementConfiguration<?> _managementConfiguration;
+
+    @Override
+    public void init(final FilterConfig filterConfig) throws ServletException
+    {
+        _managementConfiguration = 
HttpManagementUtil.getManagementConfiguration(filterConfig.getServletContext());
+    }
+
+    @Override
+    public void destroy()
+    {
+
+    }
+
+    @Override
+    public void doFilter(final ServletRequest request, final ServletResponse 
response, final FilterChain chain)
+            throws IOException, ServletException
+    {
+        final HttpServletRequest httpRequest = (HttpServletRequest) request;
+        final HttpServletResponse httpResponse = (HttpServletResponse) 
response;
+        final String method = 
String.valueOf(httpRequest.getMethod()).toUpperCase();
+
+        if (REST_API_METHODS.contains(method) || isCorsAllowedMethod(method))
+        {
+            chain.doFilter(request, response);
+        }
+        else
+        {
+            httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
+        }
+    }
+
+    private boolean isCorsAllowedMethod(final String method)
+    {
+        return _managementConfiguration.getCorsAllowMethods()
+                                       .stream()
+                                       .anyMatch(m -> 
m.equalsIgnoreCase(method));
+    }
+}
diff --git 
a/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/filter/MethodFilterTest.java
 
b/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/filter/MethodFilterTest.java
new file mode 100644
index 0000000..83eb6fc
--- /dev/null
+++ 
b/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/filter/MethodFilterTest.java
@@ -0,0 +1,92 @@
+/*
+ *
+ * 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.qpid.server.management.plugin.filter;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.qpid.server.management.plugin.HttpManagement;
+import org.apache.qpid.server.management.plugin.HttpManagementConfiguration;
+import org.apache.qpid.server.management.plugin.HttpManagementUtil;
+import org.apache.qpid.test.utils.UnitTestBase;
+
+public class MethodFilterTest extends UnitTestBase
+{
+    private MethodFilter _methodFilter;
+
+    @Before
+    public void setUp() throws Exception
+    {
+        final HttpManagementConfiguration httManagement = 
mock(HttpManagement.class);
+        
when(httManagement.getCorsAllowMethods()).thenReturn(Collections.singleton("HeAd"));
+
+        final ServletContext servletContext = mock(ServletContext.class);
+        
when(servletContext.getAttribute(HttpManagementUtil.ATTR_MANAGEMENT_CONFIGURATION)).thenReturn(httManagement);
+        FilterConfig filterConfig = mock(FilterConfig.class);
+        when(filterConfig.getServletContext()).thenReturn(servletContext);
+
+        _methodFilter = new MethodFilter();
+        _methodFilter.init(filterConfig);
+    }
+
+    @Test
+    public void testDoFilterWhenMethodAllowed() throws Exception
+    {
+        final String[] allowedMethods = {"get", "post", "put", "delete", 
"head"};
+        for (String method : allowedMethods)
+        {
+            final FilterChain chain = mock(FilterChain.class);
+            final HttpServletRequest request = mock(HttpServletRequest.class);
+            when(request.getMethod()).thenReturn(method);
+            final HttpServletResponse response = 
mock(HttpServletResponse.class);
+            _methodFilter.doFilter(request, response, chain);
+            verify(chain).doFilter(request, response);
+        }
+    }
+
+    @Test
+    public void testDoFilterWhenMethodForbidden() throws Exception
+    {
+
+        final String[] forbiddenMethods = {"option", "trace", "patch", 
"connect", "foo"};
+        for (String method : forbiddenMethods)
+        {
+            final FilterChain chain = mock(FilterChain.class);
+            final HttpServletRequest request = mock(HttpServletRequest.class);
+            when(request.getMethod()).thenReturn(method);
+            final HttpServletResponse response = 
mock(HttpServletResponse.class);
+            _methodFilter.doFilter(request, response, chain);
+            verify(response).sendError(HttpServletResponse.SC_FORBIDDEN);
+        }
+    }
+}
\ No newline at end of file

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to