Skip to content

Commit

Permalink
Merge pull request #1688 from GluuFederation/oxauth-jans-issue-1503-f…
Browse files Browse the repository at this point in the history
…or-4.4.1

feat(oxauth): added restriction for request_uri parameter (blacklist/allowed list) (4.4.1)
  • Loading branch information
yuriyz authored Jun 9, 2022
2 parents bc1ce92 + 2116ac5 commit 58c4ac9
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 17 deletions.
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());
}
}

0 comments on commit 58c4ac9

Please sign in to comment.