Upgrade owasp-java-html-sanitizer, address all fallout

Signed-off-by: Case Walker <case.b.walker@gmail.com>
This commit is contained in:
Case Walker 2024-04-12 12:49:19 -04:00 committed by Marek Posolda
parent a5a55dc66e
commit f32cd91792
20 changed files with 76 additions and 55 deletions

View file

@ -63,12 +63,6 @@
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
</dependency>
<dependency>
<!-- Included here as it provides Nonnull from com.google.code.findbugs:jsr305.
That is used in annotations in FilesPlainTextVaultProvider -->
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>owasp-java-html-sanitizer</artifactId>
</dependency>
</dependencies>
<build>

12
pom.xml
View file

@ -110,7 +110,7 @@
<resteasy-legacy.version>4.7.7.Final</resteasy-legacy.version>
<resteasy.version>6.2.7.Final</resteasy.version>
<resteasy.undertow.version>${resteasy.version}</resteasy.undertow.version>
<owasp.html.sanitizer.version>20220608.1</owasp.html.sanitizer.version>
<owasp.html.sanitizer.version>20240325.1</owasp.html.sanitizer.version>
<slf4j.version>2.0.6</slf4j.version>
<sun.istack.version>3.0.10</sun.istack.version>
<sun.saaj.version>2.0.1</sun.saaj.version>
@ -533,6 +533,16 @@
<artifactId>owasp-java-html-sanitizer</artifactId>
<version>${owasp.html.sanitizer.version}</version>
</dependency>
<dependency>
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>java8-shim</artifactId>
<version>${owasp.html.sanitizer.version}</version>
</dependency>
<dependency>
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>java10-shim</artifactId>
<version>${owasp.html.sanitizer.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

View file

@ -437,6 +437,26 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>java8-shim</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>java10-shim</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>

View file

@ -148,6 +148,14 @@
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>owasp-java-html-sanitizer</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>java8-shim</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>java10-shim</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>

View file

@ -23,7 +23,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.google.common.base.Strings;
import jakarta.ws.rs.core.MultivaluedMap;
import org.jboss.logging.Logger;
import org.keycloak.Config;
@ -43,6 +42,7 @@ import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.provider.ProviderConfigurationBuilder;
import org.keycloak.services.messages.Messages;
import org.keycloak.services.validation.Validation;
import org.keycloak.utils.StringUtil;
public abstract class AbstractRegistrationRecaptcha implements FormAction, FormActionFactory {
@ -98,7 +98,7 @@ public abstract class AbstractRegistrationRecaptcha implements FormAction, FormA
String userLanguageTag = context.getSession().getContext().resolveLocale(context.getUser())
.toLanguageTag();
boolean invisible = Boolean.parseBoolean(config.get(INVISIBLE));
String action = Strings.isNullOrEmpty(config.get(ACTION)) ? "register" : config.get(ACTION);
String action = StringUtil.isNullOrEmpty(config.get(ACTION)) ? "register" : config.get(ACTION);
form.setAttribute("recaptchaRequired", true);
form.setAttribute("recaptchaSiteKey", config.get(SITE_KEY));

View file

@ -22,7 +22,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.google.common.base.Strings;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
@ -38,6 +37,7 @@ import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.provider.ProviderConfigurationBuilder;
import org.keycloak.services.ServicesLogger;
import org.keycloak.util.JsonSerialization;
import org.keycloak.utils.StringUtil;
public class RegistrationRecaptcha extends AbstractRegistrationRecaptcha {
@ -67,7 +67,7 @@ public class RegistrationRecaptcha extends AbstractRegistrationRecaptcha {
@Override
protected boolean validateConfig(Map<String, String> config) {
return !(Strings.isNullOrEmpty(config.get(SITE_KEY)) || Strings.isNullOrEmpty(config.get(SECRET_KEY)));
return !(StringUtil.isNullOrEmpty(config.get(SITE_KEY)) || StringUtil.isNullOrEmpty(config.get(SECRET_KEY)));
}
@Override

View file

@ -24,7 +24,6 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import com.google.common.base.Strings;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
@ -38,6 +37,7 @@ import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.provider.ProviderConfigurationBuilder;
import org.keycloak.services.ServicesLogger;
import org.keycloak.util.JsonSerialization;
import org.keycloak.utils.StringUtil;
public class RegistrationRecaptchaEnterprise extends AbstractRegistrationRecaptcha {
public static final String PROVIDER_ID = "registration-recaptcha-enterprise";
@ -67,7 +67,7 @@ public class RegistrationRecaptchaEnterprise extends AbstractRegistrationRecaptc
@Override
protected boolean validateConfig(Map<String, String> config) {
return !(Stream.of(PROJECT_ID, SITE_KEY, API_KEY, ACTION)
.anyMatch(key -> Strings.isNullOrEmpty(config.get(key)))
.anyMatch(key -> StringUtil.isNullOrEmpty(config.get(key)))
|| parseDoubleFromConfig(config, SCORE_THRESHOLD) == null);
}

View file

@ -33,7 +33,7 @@ import com.webauthn4j.util.AssertUtil;
import com.webauthn4j.util.exception.WebAuthnException;
import com.webauthn4j.validator.OriginValidatorImpl;
import com.webauthn4j.validator.exception.BadOriginException;
import org.checkerframework.checker.nullness.qual.NonNull;
import jakarta.annotation.Nonnull;
import org.jboss.logging.Logger;
import org.keycloak.authentication.requiredactions.WebAuthnRegisterFactory;
import org.keycloak.common.util.Base64;
@ -248,8 +248,8 @@ public class WebAuthnCredentialProvider implements CredentialProvider<WebAuthnCr
WebAuthnAuthenticationManager webAuthnAuthenticationManager = new WebAuthnAuthenticationManager();
webAuthnAuthenticationManager.getAuthenticationDataValidator().setOriginValidator(new OriginValidatorImpl(){
@Override
protected void validate(@NonNull CollectedClientData collectedClientData,
@NonNull ServerProperty serverProperty) {
protected void validate(@Nonnull CollectedClientData collectedClientData,
@Nonnull ServerProperty serverProperty) {
AssertUtil.notNull(collectedClientData, "collectedClientData must not be null");
AssertUtil.notNull(serverProperty, "serverProperty must not be null");
final Origin clientOrigin = collectedClientData.getOrigin();

View file

@ -19,8 +19,8 @@ package org.keycloak.protocol.oid4vc.model;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.ImmutableMap;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -85,7 +85,7 @@ public class CredentialIssuer {
}
public CredentialIssuer setCredentialsSupported(Map<String, SupportedCredentialConfiguration> credentialsSupported) {
this.credentialsSupported = ImmutableMap.copyOf(credentialsSupported);
this.credentialsSupported = Collections.unmodifiableMap(credentialsSupported);
return this;
}

View file

@ -19,8 +19,8 @@ package org.keycloak.protocol.oid4vc.model;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.ImmutableList;
import java.util.Collections;
import java.util.List;
/**
@ -56,7 +56,7 @@ public class CredentialsOffer {
}
public CredentialsOffer setCredentialConfigurationIds(List<String> credentialConfigurationIds) {
this.credentialConfigurationIds = ImmutableList.copyOf(credentialConfigurationIds);
this.credentialConfigurationIds = Collections.unmodifiableList(credentialConfigurationIds);
return this;
}

View file

@ -17,8 +17,7 @@
package org.keycloak.protocol.oid4vc.model;
import com.google.common.collect.ImmutableList;
import java.util.Collections;
import java.util.List;
/**
@ -84,7 +83,7 @@ public class OID4VCClient {
}
public OID4VCClient setSupportedVCTypes(List<SupportedCredentialConfiguration> supportedVCTypes) {
this.supportedVCTypes = ImmutableList.copyOf(supportedVCTypes);
this.supportedVCTypes = Collections.unmodifiableList(supportedVCTypes);
return this;
}

View file

@ -17,9 +17,9 @@
package org.keycloak.protocol.oid4vc.model;
import com.google.common.collect.ImmutableSet;
import org.keycloak.protocol.oid4vc.issuance.mappers.OID4VCTargetRoleMapper;
import java.util.Collections;
import java.util.Objects;
import java.util.Set;
@ -37,7 +37,7 @@ public class Role {
}
public Role(Set<String> names, String target) {
this.names = ImmutableSet.copyOf(names);
this.names = Collections.unmodifiableSet(names);
this.target = target;
}

View file

@ -20,9 +20,9 @@ package org.keycloak.protocol.oid4vc.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.ImmutableList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -92,7 +92,7 @@ public class SupportedCredentialConfiguration {
}
public SupportedCredentialConfiguration setCryptographicBindingMethodsSupported(List<String> cryptographicBindingMethodsSupported) {
this.cryptographicBindingMethodsSupported = ImmutableList.copyOf(cryptographicBindingMethodsSupported);
this.cryptographicBindingMethodsSupported = Collections.unmodifiableList(cryptographicBindingMethodsSupported);
return this;
}
@ -101,7 +101,7 @@ public class SupportedCredentialConfiguration {
}
public SupportedCredentialConfiguration setCryptographicSuitesSupported(List<String> cryptographicSuitesSupported) {
this.cryptographicSuitesSupported = ImmutableList.copyOf(cryptographicSuitesSupported);
this.cryptographicSuitesSupported = Collections.unmodifiableList(cryptographicSuitesSupported);
return this;
}
@ -131,7 +131,7 @@ public class SupportedCredentialConfiguration {
}
public SupportedCredentialConfiguration setCredentialSigningAlgValuesSupported(List<String> credentialSigningAlgValuesSupported) {
this.credentialSigningAlgValuesSupported = ImmutableList.copyOf(credentialSigningAlgValuesSupported);
this.credentialSigningAlgValuesSupported = Collections.unmodifiableList(credentialSigningAlgValuesSupported);
return this;
}

View file

@ -18,15 +18,13 @@
package org.keycloak.theme;
import java.util.regex.Pattern;
import java.util.function.Predicate;
import org.owasp.html.HtmlPolicyBuilder;
import org.owasp.html.PolicyFactory;
import com.google.common.base.Predicate;
/**
* Based on the EbayPolicyExample in owasp java-html-sanitizer.
*
*/
public class KeycloakSanitizerPolicy {
@ -166,12 +164,7 @@ public class KeycloakSanitizerPolicy {
"table", "td", "th", "tr", "colgroup", "fieldset", "legend")
.toFactory();
private static Predicate<String> matchesEither(
final Pattern a, final Pattern b) {
return new Predicate<String>() {
public boolean apply(String s) {
return a.matcher(s).matches()|| b.matcher(s).matches();
}
};
private static Predicate<String> matchesEither(final Pattern a, final Pattern b) {
return s -> a.matcher(s).matches() || b.matcher(s).matches();
}
}

View file

@ -17,7 +17,6 @@
package org.keycloak.testsuite.util;
import com.google.common.base.Charsets;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.core.Form;
import jakarta.ws.rs.core.UriBuilder;
@ -524,7 +523,7 @@ public class OAuthClient {
post.addHeader("DPoP", dpopProof);
}
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters, Charsets.UTF_8);
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8);
post.setEntity(formEntity);
try {
@ -1277,7 +1276,7 @@ public class OAuthClient {
customParameters.keySet().stream().forEach(i -> parameters.add(new BasicNameValuePair(i, customParameters.get(i))));
}
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters, Charsets.UTF_8);
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8);
post.setEntity(formEntity);
try {
return new ParResponse(client.execute(post), c);

View file

@ -28,6 +28,7 @@ import static org.junit.Assert.fail;
import static org.keycloak.testsuite.util.OAuthClient.AUTH_SERVER_ROOT;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@ -42,7 +43,6 @@ import jakarta.ws.rs.core.Form;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.UriBuilder;
import com.google.common.base.Charsets;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
@ -445,7 +445,7 @@ public class UmaGrantTypeTest extends AbstractResourceServerTest {
parameters.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, OAuth2Constants.UMA_GRANT_TYPE));
parameters.add(new BasicNameValuePair("ticket", ticket));
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters, Charsets.UTF_8);
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8);
post.setEntity(formEntity);
CloseableHttpResponse response = oauth.getHttpClient().get().execute(post);

View file

@ -1,6 +1,7 @@
package org.keycloak.testsuite.client;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@ -30,8 +31,6 @@ import org.keycloak.testsuite.util.KeycloakModelUtils;
import org.keycloak.testsuite.util.MutualTLSUtils;
import org.keycloak.testsuite.util.OAuthClient;
import com.google.common.base.Charsets;
/**
* Mutual TLS Client tests.
*/
@ -278,7 +277,7 @@ public class MutualTLSClientTest extends AbstractTestRealmKeycloakTest {
parameters.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, OAuth2Constants.AUTHORIZATION_CODE));
parameters.add(new BasicNameValuePair(OAuth2Constants.CODE, oauth.getCurrentQuery().get(OAuth2Constants.CODE)));
parameters.add(new BasicNameValuePair(OAuth2Constants.REDIRECT_URI, oauth.getRedirectUri()));
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters, Charsets.UTF_8);
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8);
post.setEntity(formEntity);
return new OAuthClient.AccessTokenResponse(client.execute(post));

View file

@ -1,6 +1,5 @@
package org.keycloak.testsuite.saml;
import com.google.common.base.Charsets;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;
import org.hamcrest.Matchers;
@ -49,6 +48,7 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
@ -190,7 +190,7 @@ public class ArtifactBindingTest extends AbstractSamlTest {
assertThat(artifact[3], is((byte)0));
MessageDigest sha1Digester = MessageDigest.getInstance("SHA-1");
byte[] source = sha1Digester.digest(getAuthServerRealmBase(REALM_NAME).toString().getBytes(Charsets.UTF_8));
byte[] source = sha1Digester.digest(getAuthServerRealmBase(REALM_NAME).toString().getBytes(StandardCharsets.UTF_8));
for (int i = 0; i < 20; i++) {
assertThat(source[i], is(artifact[i+4]));
}
@ -450,7 +450,7 @@ public class ArtifactBindingTest extends AbstractSamlTest {
assertThat(artifact[3], is((byte)0));
MessageDigest sha1Digester = MessageDigest.getInstance("SHA-1");
byte[] source = sha1Digester.digest(getAuthServerRealmBase(REALM_NAME).toString().getBytes(Charsets.UTF_8));
byte[] source = sha1Digester.digest(getAuthServerRealmBase(REALM_NAME).toString().getBytes(StandardCharsets.UTF_8));
for (int i = 0; i < 20; i++) {
assertThat(source[i], is(artifact[i+4]));
}

View file

@ -1,9 +1,8 @@
package org.keycloak.testsuite.x509;
import com.google.common.base.Charsets;
import io.undertow.Undertow;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.function.Supplier;
@ -81,7 +80,7 @@ public class X509OCSPResponderFailOpenTest extends AbstractX509AuthenticationTes
.setMappingSourceType(SUBJECTDN_EMAIL)
.setOCSPResponder("http://" + OCSP_RESPONDER_HOST + ".invalid.host:" + OCSP_RESPONDER_PORT + "/oscp")
.setOCSPResponderCertificate(
IOUtils.toString(this.getClass().getResourceAsStream(OcspHandler.OCSP_RESPONDER_CERT_PATH), Charsets.UTF_8)
IOUtils.toString(this.getClass().getResourceAsStream(OcspHandler.OCSP_RESPONDER_CERT_PATH), StandardCharsets.UTF_8)
.replace("-----BEGIN CERTIFICATE-----", "")
.replace("-----END CERTIFICATE-----", ""))
.setUserIdentityMapperType(USERNAME_EMAIL);

View file

@ -18,7 +18,6 @@
package org.keycloak.testsuite.x509;
import com.google.common.base.Charsets;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.junit.After;
import org.junit.Assert;
@ -40,6 +39,7 @@ import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorC
import io.undertow.Undertow;
import io.undertow.server.handlers.BlockingHandler;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.function.Supplier;
import org.apache.commons.io.IOUtils;
@ -164,7 +164,7 @@ public class X509OCSPResponderTest extends AbstractX509AuthenticationTest {
.setMappingSourceType(SUBJECTDN_EMAIL)
.setOCSPResponder("http://" + OCSP_RESPONDER_HOST + ":" + OCSP_RESPONDER_PORT + "/oscp")
.setOCSPResponderCertificate(
IOUtils.toString(this.getClass().getResourceAsStream(OcspHandler.OCSP_RESPONDER_CERT_PATH), Charsets.UTF_8)
IOUtils.toString(this.getClass().getResourceAsStream(OcspHandler.OCSP_RESPONDER_CERT_PATH), StandardCharsets.UTF_8)
.replace(PemUtils.BEGIN_CERT, "")
.replace(PemUtils.END_CERT, ""))
.setUserIdentityMapperType(USERNAME_EMAIL);