KEYCLOAK-14107 Admin page content blocked on v10.0.0 due to content security policy

This commit is contained in:
stianst 2020-05-26 10:53:40 +02:00 committed by Marek Posolda
parent 4265fdcab2
commit 90b29b0e31
4 changed files with 19 additions and 7 deletions

View file

@ -97,9 +97,9 @@ public class BrowserSecurityHeaders {
public static class ContentSecurityPolicyBuilder {
private String frameSrc = "self";
private String frameAncestors = "self";
private String objectSrc = "none";
private String frameSrc = "'self'";
private String frameAncestors = "'self'";
private String objectSrc = "'none'";
private boolean first;
private StringBuilder sb;
@ -136,7 +136,7 @@ public class BrowserSecurityHeaders {
}
first = false;
sb.append(k).append(" '").append(v).append("';");
sb.append(k).append(" ").append(v).append(";");
}
}

View file

@ -11,7 +11,7 @@ public class BrowserSecurityHeadersTest {
assertEquals("frame-src 'self'; frame-ancestors 'self'; object-src 'none';", BrowserSecurityHeaders.ContentSecurityPolicyBuilder.create().build());
assertEquals("frame-ancestors 'self'; object-src 'none';", BrowserSecurityHeaders.ContentSecurityPolicyBuilder.create().frameSrc(null).build());
assertEquals("frame-src 'self'; object-src 'none';", BrowserSecurityHeaders.ContentSecurityPolicyBuilder.create().frameAncestors(null).build());
assertEquals("frame-src 'custom-frame-src'; frame-ancestors 'custom-frame-ancestors'; object-src 'none';", BrowserSecurityHeaders.ContentSecurityPolicyBuilder.create().frameSrc("custom-frame-src").frameAncestors("custom-frame-ancestors").build());
assertEquals("frame-src 'custom-frame-src'; frame-ancestors 'custom-frame-ancestors'; object-src 'none';", BrowserSecurityHeaders.ContentSecurityPolicyBuilder.create().frameSrc("'custom-frame-src'").frameAncestors("'custom-frame-ancestors'").build());
}
}

View file

@ -25,6 +25,7 @@ import javax.ws.rs.NotFoundException;
import org.keycloak.Config;
import org.keycloak.common.ClientConnection;
import org.keycloak.common.Version;
import org.keycloak.common.util.UriUtils;
import org.keycloak.headers.SecurityHeadersProvider;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.ClientModel;
@ -309,7 +310,7 @@ public class AdminConsole {
// Replace CSP if admin is hosted on different URL
if (!adminBaseUri.equals(authServerBaseUri)) {
session.getProvider(SecurityHeadersProvider.class).options().allowFrameSrc(UriBuilder.fromUri(authServerBaseUri).replacePath("").build().toString());
session.getProvider(SecurityHeadersProvider.class).options().allowFrameSrc(UriUtils.getOrigin(authServerBaseUri));
}
return builder.build();

View file

@ -14,8 +14,10 @@ import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.client.registration.Auth;
import org.keycloak.client.registration.ClientRegistration;
import org.keycloak.client.registration.ClientRegistrationException;
import org.keycloak.common.util.UriUtils;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.JWSInputException;
import org.keycloak.models.BrowserSecurityHeaders;
import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.JsonWebToken;
@ -246,12 +248,21 @@ public class DefaultHostnameTest extends AbstractHostnameTest {
private void assertAdminPage(String realm, String expectedFrontendUrl, String expectedAdminUrl) throws IOException, URISyntaxException {
try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
String indexPage = SimpleHttp.doGet(AUTH_SERVER_ROOT + "/admin/" + realm +"/console/", client).asString();
SimpleHttp.Response response = SimpleHttp.doGet(AUTH_SERVER_ROOT + "/admin/" + realm +"/console/", client).asResponse();
String indexPage = response.asString();
assertTrue(indexPage.contains("authServerUrl = '" + expectedFrontendUrl +"'"));
assertTrue(indexPage.contains("authUrl = '" + expectedAdminUrl +"'"));
assertTrue(indexPage.contains("consoleBaseUrl = '" + new URI(expectedAdminUrl).getPath() +"/admin/" + realm + "/console/'"));
assertTrue(indexPage.contains("resourceUrl = '" + new URI(expectedAdminUrl).getPath() +"/resources/"));
String cspHeader = response.getFirstHeader(BrowserSecurityHeaders.CONTENT_SECURITY_POLICY);
if (expectedFrontendUrl.equalsIgnoreCase(expectedAdminUrl)) {
assertEquals("frame-src 'self'; frame-ancestors 'self'; object-src 'none';", cspHeader);
} else {
assertEquals("frame-src " + UriUtils.getOrigin(expectedFrontendUrl) + "; frame-ancestors 'self'; object-src 'none';", cspHeader);
}
}
}