Preventing post requests. Issue #319

This commit is contained in:
Markus Kreusch
2016-08-09 20:02:06 +02:00
parent 93d3eca0ab
commit df7e9a0af1
3 changed files with 95 additions and 0 deletions

View File

@@ -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));

View File

@@ -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);
}
}

View File

@@ -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
}
}