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