SEC-1998: DummyRequest extend HttpServletRequestWrapper

Previously DummyRequest implemented HttpServletRequest which caused complications
since Servlet 2.5 and Servlet 3 had non passive changes. While we were "safe" if the
Servlet 3 methods were never invoked reflective access of the methods would also
problems. We could prevent users from accessing the methods of DummyRequest by
returning new HttpServletRequestWrapper(DummyRequest), but a debugger could
potentially try to iterate over the methods triggering a NoClassDefFoundError.

DummyRequest now extends HttpServletRequestWrapper which will be dynamically
linked to the proper version of HttpServletRequest. We use a Dynamic Proxy that
throws UnsupportedOperationException to implement any methods we are not
interested in.
This commit is contained in:
Rob Winch 2012-12-07 09:20:07 -06:00
parent 3437ef714a
commit 1a650acbcc
1 changed files with 18 additions and 262 deletions

View File

@ -16,31 +16,23 @@
package org.springframework.security.web;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
import javax.servlet.AsyncContext;
import javax.servlet.DispatcherType;
import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import org.springframework.security.web.util.UrlUtils;
@ -154,8 +146,10 @@ public class FilterInvocation {
}
}
@SuppressWarnings({"unchecked"})
class DummyRequest implements HttpServletRequest {
class DummyRequest extends HttpServletRequestWrapper {
private static final HttpServletRequest UNSUPPORTED_REQUEST = (HttpServletRequest) Proxy.newProxyInstance(
DummyRequest.class.getClassLoader(), new Class[] { HttpServletRequest.class }, new UnsupportedOperationExceptionInvocationHandler());
private String requestURI;
private String contextPath = "";
private String servletPath;
@ -163,6 +157,10 @@ class DummyRequest implements HttpServletRequest {
private String queryString;
private String method;
public DummyRequest() {
super(UNSUPPORTED_REQUEST);
}
public void setRequestURI(String requestURI) {
this.requestURI = requestURI;
}
@ -210,254 +208,6 @@ class DummyRequest implements HttpServletRequest {
public void setQueryString(String queryString) {
this.queryString = queryString;
}
public String getAuthType() {
throw new UnsupportedOperationException();
}
public Cookie[] getCookies() {
throw new UnsupportedOperationException();
}
public long getDateHeader(String name) {
throw new UnsupportedOperationException();
}
public String getHeader(String name) {
throw new UnsupportedOperationException();
}
@SuppressWarnings("rawtypes")
public Enumeration getHeaderNames() {
throw new UnsupportedOperationException();
}
@SuppressWarnings("rawtypes")
public Enumeration getHeaders(String name) {
throw new UnsupportedOperationException();
}
public int getIntHeader(String name) {
throw new UnsupportedOperationException();
}
public String getPathTranslated() {
throw new UnsupportedOperationException();
}
public String getRemoteUser() {
throw new UnsupportedOperationException();
}
public StringBuffer getRequestURL() {
throw new UnsupportedOperationException();
}
public String getRequestedSessionId() {
throw new UnsupportedOperationException();
}
public HttpSession getSession() {
throw new UnsupportedOperationException();
}
public HttpSession getSession(boolean create) {
throw new UnsupportedOperationException();
}
public Principal getUserPrincipal() {
throw new UnsupportedOperationException();
}
public boolean isRequestedSessionIdFromCookie() {
throw new UnsupportedOperationException();
}
public boolean isRequestedSessionIdFromURL() {
throw new UnsupportedOperationException();
}
public boolean isRequestedSessionIdFromUrl() {
throw new UnsupportedOperationException();
}
public boolean isRequestedSessionIdValid() {
throw new UnsupportedOperationException();
}
public boolean isUserInRole(String role) {
throw new UnsupportedOperationException();
}
public Object getAttribute(String name) {
throw new UnsupportedOperationException();
}
@SuppressWarnings("rawtypes")
public Enumeration getAttributeNames() {
throw new UnsupportedOperationException();
}
public String getCharacterEncoding() {
throw new UnsupportedOperationException();
}
public int getContentLength() {
throw new UnsupportedOperationException();
}
public String getContentType() {
throw new UnsupportedOperationException();
}
public ServletInputStream getInputStream() throws IOException {
throw new UnsupportedOperationException();
}
public String getLocalAddr() {
throw new UnsupportedOperationException();
}
public String getLocalName() {
throw new UnsupportedOperationException();
}
public int getLocalPort() {
throw new UnsupportedOperationException();
}
public Locale getLocale() {
throw new UnsupportedOperationException();
}
@SuppressWarnings("rawtypes")
public Enumeration getLocales() {
throw new UnsupportedOperationException();
}
public String getParameter(String name) {
throw new UnsupportedOperationException();
}
@SuppressWarnings("rawtypes")
public Map getParameterMap() {
throw new UnsupportedOperationException();
}
@SuppressWarnings("rawtypes")
public Enumeration getParameterNames() {
throw new UnsupportedOperationException();
}
public String[] getParameterValues(String name) {
throw new UnsupportedOperationException();
}
public String getProtocol() {
throw new UnsupportedOperationException();
}
public BufferedReader getReader() throws IOException {
throw new UnsupportedOperationException();
}
public String getRealPath(String path) {
throw new UnsupportedOperationException();
}
public String getRemoteAddr() {
throw new UnsupportedOperationException();
}
public String getRemoteHost() {
throw new UnsupportedOperationException();
}
public int getRemotePort() {
throw new UnsupportedOperationException();
}
public RequestDispatcher getRequestDispatcher(String path) {
throw new UnsupportedOperationException();
}
public String getScheme() {
throw new UnsupportedOperationException();
}
public String getServerName() {
throw new UnsupportedOperationException();
}
public int getServerPort() {
throw new UnsupportedOperationException();
}
public boolean isSecure() {
throw new UnsupportedOperationException();
}
public void removeAttribute(String name) {
throw new UnsupportedOperationException();
}
public void setAttribute(String name, Object o) {
throw new UnsupportedOperationException();
}
public void setCharacterEncoding(String env) throws UnsupportedEncodingException {
throw new UnsupportedOperationException();
}
public ServletContext getServletContext() {
throw new UnsupportedOperationException();
}
public AsyncContext startAsync() {
throw new UnsupportedOperationException();
}
public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) {
throw new UnsupportedOperationException();
}
public boolean isAsyncStarted() {
throw new UnsupportedOperationException();
}
public boolean isAsyncSupported() {
throw new UnsupportedOperationException();
}
public AsyncContext getAsyncContext() {
throw new UnsupportedOperationException();
}
public DispatcherType getDispatcherType() {
throw new UnsupportedOperationException();
}
public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
throw new UnsupportedOperationException();
}
public void login(String username, String password) throws ServletException {
throw new UnsupportedOperationException();
}
public void logout() throws ServletException {
throw new UnsupportedOperationException();
}
public Collection<Part> getParts() throws IOException, IllegalStateException, ServletException {
throw new UnsupportedOperationException();
}
public Part getPart(String name) throws IOException, IllegalStateException, ServletException {
throw new UnsupportedOperationException();
}
}
class DummyResponse implements HttpServletResponse {
@ -606,3 +356,9 @@ class DummyResponse implements HttpServletResponse {
throw new UnsupportedOperationException();
}
}
final class UnsupportedOperationExceptionInvocationHandler implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
throw new UnsupportedOperationException(method + " is not supported");
}
}