Skip to content

Commit

Permalink
Added RestrictedHttpServletRequest to enhance security by limiting re…
Browse files Browse the repository at this point in the history
…quest modifications
  • Loading branch information
imsayari404 authored and sayarimukherjee committed Dec 13, 2024
1 parent 1ccdc8e commit 1ad5092
Show file tree
Hide file tree
Showing 4 changed files with 262 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import com.facebook.airlift.http.server.AuthenticationException;
import com.facebook.airlift.http.server.Authenticator;
import com.facebook.presto.spi.security.RestrictedHttpServletRequest;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
Expand All @@ -40,7 +41,9 @@ public Principal authenticate(HttpServletRequest request)
throws AuthenticationException
{
try {
return authenticatorManager.getAuthenticator().createAuthenticatedPrincipal(request);
//wrapped the original HttpServletRequest in a RestrictedHttpServletRequest
RestrictedHttpServletRequest restrictedRequest = new RestrictedHttpServletRequest(request);
return authenticatorManager.getAuthenticator().createAuthenticatedPrincipal(restrictedRequest);
}
catch (RuntimeException e) {
throw new RuntimeException("Authentication error", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
import com.facebook.presto.spi.security.AccessDeniedException;
import com.facebook.presto.spi.security.PrestoAuthenticator;
import com.facebook.presto.spi.security.PrestoAuthenticatorFactory;
import com.facebook.presto.spi.security.RestrictedHttpServletRequest;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import org.testng.annotations.Test;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;
import java.security.Principal;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -62,7 +64,10 @@ public void testPrestoAuthenticator()
TEST_REMOTE_ADDRESS,
ImmutableMap.of());

Optional<Principal> principal = checkAuthentication(prestoAuthenticatorManager.getAuthenticator(), request);
// Wrap the request in RestrictedHttpServletRequest
RestrictedHttpServletRequest restrictedRequest = new RestrictedHttpServletRequest(request);

Optional<Principal> principal = checkAuthentication(prestoAuthenticatorManager.getAuthenticator(), restrictedRequest);
assertTrue(principal.isPresent());
assertEquals(principal.get().getName(), TEST_USER);

Expand All @@ -72,11 +77,27 @@ public void testPrestoAuthenticator()
TEST_REMOTE_ADDRESS,
ImmutableMap.of());

principal = checkAuthentication(prestoAuthenticatorManager.getAuthenticator(), request);
restrictedRequest = new RestrictedHttpServletRequest(request);

principal = checkAuthentication(prestoAuthenticatorManager.getAuthenticator(), restrictedRequest);
assertFalse(principal.isPresent());
}

private Optional<Principal> checkAuthentication(PrestoAuthenticator authenticator, HttpServletRequest request)
@Test(expectedExceptions = UnsupportedOperationException.class)
public void testRestrictedHttpServletRequestDisallowedMethods() throws IOException
{
HttpServletRequest mockRequest = new MockHttpServletRequest(
ImmutableListMultimap.of(TEST_HEADER, TEST_HEADER_VALID_VALUE + ":" + TEST_USER),
TEST_REMOTE_ADDRESS,
ImmutableMap.of());

RestrictedHttpServletRequest restrictedRequest = new RestrictedHttpServletRequest(mockRequest);

// Attempt to call a disallowed method
restrictedRequest.getInputStream(); // Should throw UnsupportedOperationException
}

private Optional<Principal> checkAuthentication(PrestoAuthenticator authenticator, RestrictedHttpServletRequest request)
{
try {
return Optional.of(authenticator.createAuthenticatedPrincipal(request));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
*/
package com.facebook.presto.spi.security;

import javax.servlet.http.HttpServletRequest;

import java.security.Principal;

public interface PrestoAuthenticator
Expand All @@ -25,5 +23,5 @@ public interface PrestoAuthenticator
* @return the authenticated Principal
* @throws AccessDeniedException if not allowed
*/
Principal createAuthenticatedPrincipal(HttpServletRequest request);
Principal createAuthenticatedPrincipal(RestrictedHttpServletRequest request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
/*
* Licensed 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 com.facebook.presto.spi.security;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpSession;

import java.io.BufferedReader;
import java.io.IOException;
import java.security.Principal;
import java.util.Enumeration;
import java.util.Map;

public class RestrictedHttpServletRequest
extends HttpServletRequestWrapper
{
/**
* Constructs a request object wrapping the given request.
*
* @param request
* @throws IllegalArgumentException if the request is null
*/
public RestrictedHttpServletRequest(HttpServletRequest request)
{
super(request);
}

@Override
public BufferedReader getReader() throws IOException
{
throw new UnsupportedOperationException("Reading the request body via getReader is not supported.");
}

@Override
public javax.servlet.ServletInputStream getInputStream() throws IOException
{
throw new UnsupportedOperationException("Reading the request body via getInputStream is not supported.");
}

@Override
public void setAttribute(String name, Object o)
{
throw new UnsupportedOperationException("Modifying request attributes is not supported.");
}

@Override
public void removeAttribute(String name)
{
throw new UnsupportedOperationException("Modifying request attributes is not supported.");
}

// Delegate all other methods to the wrapped request
@Override
public String getAuthType()
{
return super.getAuthType();
}

@Override
public Cookie[] getCookies()
{
return super.getCookies();
}

@Override
public long getDateHeader(String name)
{
return super.getDateHeader(name);
}

@Override
public String getHeader(String name)
{
return super.getHeader(name);
}

@Override
public Enumeration<String> getHeaders(String name)
{
return super.getHeaders(name);
}

@Override
public Enumeration<String> getHeaderNames()
{
return super.getHeaderNames();
}

@Override
public int getIntHeader(String name)
{
return super.getIntHeader(name);
}

@Override
public String getMethod()
{
return super.getMethod();
}

@Override
public String getPathInfo()
{
return super.getPathInfo();
}

@Override
public String getPathTranslated()
{
return super.getPathTranslated();
}

@Override
public String getContextPath()
{
return super.getContextPath();
}

@Override
public String getQueryString()
{
return super.getQueryString();
}

@Override
public String getRemoteUser()
{
return super.getRemoteUser();
}

@Override
public boolean isUserInRole(String role)
{
return super.isUserInRole(role);
}

@Override
public Principal getUserPrincipal()
{
return super.getUserPrincipal();
}

@Override
public String getRequestedSessionId()
{
return super.getRequestedSessionId();
}

@Override
public String getRequestURI()
{
return super.getRequestURI();
}

@Override
public StringBuffer getRequestURL()
{
return super.getRequestURL();
}

@Override
public String getServletPath()
{
return super.getServletPath();
}

@Override
public HttpSession getSession(boolean create)
{
return super.getSession(create);
}

@Override
public HttpSession getSession()
{
return super.getSession();
}

@Override
public String changeSessionId()
{
return super.changeSessionId();
}

@Override
public boolean isRequestedSessionIdValid()
{
return super.isRequestedSessionIdValid();
}

@Override
public boolean isRequestedSessionIdFromCookie()
{
return super.isRequestedSessionIdFromCookie();
}

@Override
public boolean isRequestedSessionIdFromURL()
{
return super.isRequestedSessionIdFromURL();
}

@Override
public boolean isRequestedSessionIdFromUrl()
{
return super.isRequestedSessionIdFromUrl();
}

@Override
public Map<String, String[]> getParameterMap()
{
return super.getParameterMap();
}

@Override
public String[] getParameterValues(String name)
{
return super.getParameterValues(name);
}
}

0 comments on commit 1ad5092

Please sign in to comment.