Przeglądaj źródła

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.
Rob Winch 12 lat temu
rodzic
commit
1a650acbcc

+ 18 - 262
web/src/main/java/org/springframework/security/web/FilterInvocation.java

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