Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(oxauth): added restriction for request_uri parameter (blacklist/allowed list) (4.5) #1687

Merged
merged 1 commit into from
Jun 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ public class AppConfiguration implements Configuration {
private Boolean requestUriParameterSupported;
private Boolean requestUriHashVerificationEnabled;
private Boolean requireRequestUriRegistration;
private List<String> requestUriBlackList;
private String opPolicyUri;
private String opTosUri;
private int authorizationCodeLifetime;
Expand Down Expand Up @@ -2089,6 +2090,15 @@ public void setCibaEnabled(Boolean cibaEnabled) {
this.cibaEnabled = cibaEnabled;
}

public List<String> getRequestUriBlackList() {
if (requestUriBlackList == null) requestUriBlackList = Lists.newArrayList();
return requestUriBlackList;
}

public void setRequestUriBlackList(List<String> requestUriBlackList) {
this.requestUriBlackList = requestUriBlackList;
}

public Boolean getRequestUriHashVerificationEnabled() {
return requestUriHashVerificationEnabled != null ? requestUriHashVerificationEnabled : false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,9 @@

package org.gluu.oxauth.model.authorize;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Response;

import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.gluu.oxauth.model.common.Display;
import org.gluu.oxauth.model.common.Prompt;
import org.gluu.oxauth.model.common.ResponseType;
Expand All @@ -27,6 +17,7 @@
import org.gluu.oxauth.model.crypto.encryption.BlockEncryptionAlgorithm;
import org.gluu.oxauth.model.crypto.encryption.KeyEncryptionAlgorithm;
import org.gluu.oxauth.model.crypto.signature.SignatureAlgorithm;
import org.gluu.oxauth.model.error.ErrorResponseFactory;
import org.gluu.oxauth.model.exception.InvalidJwtException;
import org.gluu.oxauth.model.jwe.Jwe;
import org.gluu.oxauth.model.jwe.JweDecrypterImpl;
Expand All @@ -35,9 +26,11 @@
import org.gluu.oxauth.model.registration.Client;
import org.gluu.oxauth.model.util.Base64Util;
import org.gluu.oxauth.model.util.JwtUtil;
import org.gluu.oxauth.model.util.URLPatternList;
import org.gluu.oxauth.model.util.Util;
import org.gluu.oxauth.service.ClientService;
import org.gluu.oxauth.service.RedirectUriResponse;
import org.gluu.oxauth.service.RedirectionUriService;
import org.gluu.oxauth.util.ServerUtil;
import org.gluu.service.cdi.util.CdiUtil;
import org.jetbrains.annotations.Nullable;
Expand All @@ -47,8 +40,16 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Response;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.List;

/**
* @author Javier Rojas Blum
Expand Down Expand Up @@ -462,6 +463,7 @@ private static String queryRequest(@Nullable String requestUri, @Nullable Redire
}

public static JwtAuthorizationRequest createJwtRequest(String request, String requestUri, Client client, RedirectUriResponse redirectUriResponse, AbstractCryptoProvider cryptoProvider, AppConfiguration appConfiguration) {
validateRequestUri(requestUri, client, appConfiguration, redirectUriResponse.getState());
final String requestFromClient = queryRequest(requestUri, redirectUriResponse, appConfiguration);
if (StringUtils.isNotBlank(requestFromClient)) {
request = requestFromClient;
Expand All @@ -481,4 +483,35 @@ public static JwtAuthorizationRequest createJwtRequest(String request, String re
return null;
}

public static void validateRequestUri(String requestUri, Client client, AppConfiguration appConfiguration, String state) {
validateRequestUri(requestUri, client, appConfiguration, state, CdiUtil.bean(ErrorResponseFactory.class));
}

public static void validateRequestUri(String requestUri, Client client, AppConfiguration appConfiguration, String state, ErrorResponseFactory errorResponseFactory) {
if (StringUtils.isBlank(requestUri)) {
return; // nothing to validate
}

// client.requestUris() - validation
if (ArrayUtils.isNotEmpty(client.getRequestUris()) && !RedirectionUriService.isUriEqual(requestUri, client.getRequestUris())) {
log.debug("request_uri is forbidden by client request uris.");
throw new WebApplicationException(Response
.status(Response.Status.BAD_REQUEST)
.entity(errorResponseFactory.getErrorAsJson(AuthorizeErrorResponseType.INVALID_REQUEST_URI, state, ""))
.build());
}

// check black list
final List<String> blackList = appConfiguration.getRequestUriBlackList();
if (!blackList.isEmpty()) {
URLPatternList urlPatternList = new URLPatternList(blackList);
if (urlPatternList.isUrlListed(requestUri)) {
log.debug("request_uri is forbidden by requestUriBlackList configuration.");
throw new WebApplicationException(Response
.status(Response.Status.BAD_REQUEST)
.entity(errorResponseFactory.getErrorAsJson(AuthorizeErrorResponseType.INVALID_REQUEST_URI, state, ""))
.build());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ public void setState(String state) {
this.state = state;
}

public String getState() {
return state;
}

public Response.ResponseBuilder createErrorBuilder(IErrorType errorType) {
redirectUri.parseQueryString(errorFactory.getErrorAsQueryString(errorType, state));
return RedirectUtil.getRedirectResponseBuilder(redirectUri, httpRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.slf4j.LoggerFactory;

/**
* @author Javier Rojas Blum
Expand All @@ -39,8 +40,7 @@
@ApplicationScoped
public class RedirectionUriService {

@Inject
private Logger log;
private static final Logger log = LoggerFactory.getLogger(RedirectionUriService.class);

@Inject
private ClientService clientService;
Expand Down Expand Up @@ -125,7 +125,7 @@ public String validateRedirectionUri(@NotNull Client client, String redirectionU
return null;
}

public boolean isUriEqual(String redirectionUri, String[] redirectUris) {
public static boolean isUriEqual(String redirectionUri, String[] redirectUris) {
final String redirectUriWithoutParams = uriWithoutParams(redirectionUri);

for (String uri : redirectUris) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.gluu.oxauth.model.authorize;

import org.gluu.oxauth.model.configuration.AppConfiguration;
import org.gluu.oxauth.model.error.ErrorResponseFactory;
import org.gluu.oxauth.model.registration.Client;
import org.testng.annotations.Test;

import javax.ws.rs.WebApplicationException;
import java.util.Arrays;
import java.util.Collections;

/**
* @author Yuriy Zabrovarnyy
*/
public class JwtAuthorizationRequestTest {

@Test
public void validateRequestUri_whichIsAllowedByClient_shouldBeOk() {
String requestUri = "https://myrp.com/request_uri";

Client client = new Client();
client.setRequestUris(new String[]{"https://myrp.com/request_uri"});
JwtAuthorizationRequest.validateRequestUri(requestUri, client, new AppConfiguration(), "", new ErrorResponseFactory());
}

@Test
public void validateRequestUri_withNoRestrictions_shouldBeOk() {
String requestUri = "https://myrp.com/request_uri";

JwtAuthorizationRequest.validateRequestUri(requestUri, new Client(), new AppConfiguration(), "", new ErrorResponseFactory());
}

@Test(expectedExceptions = WebApplicationException.class)
public void validateRequestUri_whichIsNotAllowedByClient_shouldRaiseException() {
String requestUri = "https://myrp.com/request_uri";

Client client = new Client();
client.setRequestUris(new String[]{"https://myrp.com"});
JwtAuthorizationRequest.validateRequestUri(requestUri, client, new AppConfiguration(), "", new ErrorResponseFactory());
}

@Test(expectedExceptions = WebApplicationException.class)
public void validateRequestUri_whichIsBlackListed_shouldRaiseException() {
String requestUri = "https://myrp.com/request_uri";

final AppConfiguration appConfiguration = new AppConfiguration();
appConfiguration.setRequestUriBlackList(Arrays.asList("myrp.com", "evil.com"));
JwtAuthorizationRequest.validateRequestUri(requestUri, new Client(), appConfiguration, "", new ErrorResponseFactory());
}

@Test(expectedExceptions = WebApplicationException.class)
public void validateRequestUri_forLocalhost_shouldRaiseException() {
String requestUri = "https://localhost/request_uri";

final AppConfiguration appConfiguration = new AppConfiguration();
appConfiguration.setRequestUriBlackList(Collections.singletonList("localhost"));
JwtAuthorizationRequest.validateRequestUri(requestUri, new Client(), appConfiguration, "", new ErrorResponseFactory());
}

@Test(expectedExceptions = WebApplicationException.class)
public void validateRequestUri_forLocalhostIp_shouldRaiseException() {
String requestUri = "https://127.0.0.1/request_uri";

final AppConfiguration appConfiguration = new AppConfiguration();
appConfiguration.setRequestUriBlackList(Collections.singletonList("127.0.0.1"));
JwtAuthorizationRequest.validateRequestUri(requestUri, new Client(), appConfiguration, "", new ErrorResponseFactory());
}

@Test
public void validateRequestUri_whichIsNotBlackListed_shouldBeOk() {
String requestUri = "https://myrp.com/request_uri";

final AppConfiguration appConfiguration = new AppConfiguration();
appConfiguration.setRequestUriBlackList(Arrays.asList("evil.com", "second.com"));
JwtAuthorizationRequest.validateRequestUri(requestUri, new Client(), appConfiguration, "", new ErrorResponseFactory());
}
}