Browse Source

Preventing post requests. Issue #319

Markus Kreusch 8 years ago
parent
commit
df7e9a0af1

+ 2 - 0
main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavServletContextFactory.java

@@ -22,6 +22,7 @@ import org.cryptomator.frontend.webdav.filters.AcceptRangeFilter;
 import org.cryptomator.frontend.webdav.filters.LoopbackFilter;
 import org.cryptomator.frontend.webdav.filters.MacChunkedPutCompatibilityFilter;
 import org.cryptomator.frontend.webdav.filters.MkcolComplianceFilter;
+import org.cryptomator.frontend.webdav.filters.PostRequestBlockingFilter;
 import org.cryptomator.frontend.webdav.filters.UriNormalizationFilter;
 import org.cryptomator.frontend.webdav.filters.UriNormalizationFilter.ResourceTypeChecker;
 import org.cryptomator.frontend.webdav.filters.UriNormalizationFilter.ResourceTypeChecker.ResourceType;
@@ -67,6 +68,7 @@ class WebDavServletContextFactory {
 		final ServletHolder servletHolder = new ServletHolder(contextPath, new WebDavServlet(contextRoot, root));
 		servletContext.addServlet(servletHolder, WILDCARD);
 		servletContext.addFilter(LoopbackFilter.class, WILDCARD, EnumSet.of(DispatcherType.REQUEST));
+		servletContext.addFilter(PostRequestBlockingFilter.class, WILDCARD, EnumSet.of(DispatcherType.REQUEST));
 		servletContext.addFilter(MkcolComplianceFilter.class, WILDCARD, EnumSet.of(DispatcherType.REQUEST));
 		servletContext.addFilter(AcceptRangeFilter.class, WILDCARD, EnumSet.of(DispatcherType.REQUEST));
 		servletContext.addFilter(new FilterHolder(new UriNormalizationFilter(resourceTypeChecker)), WILDCARD, EnumSet.of(DispatcherType.REQUEST));

+ 43 - 0
main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/filters/PostFromAllowHeaderRemovingHttpServletResponseWrapper.java

@@ -0,0 +1,43 @@
+package org.cryptomator.frontend.webdav.filters;
+
+import static java.util.Arrays.stream;
+import static java.util.function.Predicate.isEqual;
+import static java.util.stream.Collectors.joining;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+class PostFromAllowHeaderRemovingHttpServletResponseWrapper extends HttpServletResponseWrapper {
+	
+	public PostFromAllowHeaderRemovingHttpServletResponseWrapper(HttpServletResponse response) {
+		super(response);
+	}
+
+	@Override
+	public void addHeader(String name, String value) {
+		if (isAllowHeader(name)) {
+			super.setHeader(name, removePost(value));
+		} else {
+			super.addHeader(name, value);
+		}
+	}
+
+	@Override
+	public void setHeader(String name, String value) {
+		if (isAllowHeader(name)) {
+			super.setHeader(name, removePost(value));
+		} else {
+			super.setHeader(name, value);
+		}
+	}
+
+	private String removePost(String value) {
+		return stream(value.split("\\s*,\\s*"))
+				.filter(isEqual("POST").negate())
+				.collect(joining(", "));
+	}
+
+	private boolean isAllowHeader(String name) {
+		return "allow".equalsIgnoreCase(name);
+	}
+}

+ 50 - 0
main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/filters/PostRequestBlockingFilter.java

@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Sebastian Stenzel and others.
+ * This file is licensed under the terms of the MIT license.
+ * See the LICENSE.txt file for more info.
+ *
+ * Contributors:
+ *     Sebastian Stenzel - initial API and implementation
+ *******************************************************************************/
+package org.cryptomator.frontend.webdav.filters;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Blocks all post requests.
+ */
+public class PostRequestBlockingFilter implements HttpFilter {
+
+	private static final String POST_METHOD = "POST";
+
+	@Override
+	public void init(FilterConfig filterConfig) throws ServletException {
+		// no-op
+	}
+	
+	@Override
+	public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
+			throws IOException, ServletException {
+		if (isPost(request)) {
+			response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+		} else {
+			chain.doFilter(request, new PostFromAllowHeaderRemovingHttpServletResponseWrapper(response));
+		}
+	}
+
+	private boolean isPost(HttpServletRequest request) {
+		return POST_METHOD.equalsIgnoreCase(request.getMethod());
+	}
+
+	@Override
+	public void destroy() {
+		// no-op
+	}
+
+}