KEYCLOAK-14232 Add Referrer-Policy: no-referrer to each response from Keycloak

(cherry picked from commit 0b49640231abc6e465542bd2608e1c908c079ced)
This commit is contained in:
mhajas 2020-06-17 14:31:08 +02:00 committed by Stian Thorgersen
parent f037dabdc1
commit f7e0af438d
11 changed files with 140 additions and 159 deletions

View file

@ -21,125 +21,54 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** public enum BrowserSecurityHeaders {
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class BrowserSecurityHeaders {
public static final String X_FRAME_OPTIONS = "X-Frame-Options"; X_FRAME_OPTIONS("xFrameOptions", "X-Frame-Options", "SAMEORIGIN"),
CONTENT_SECURITY_POLICY("contentSecurityPolicy", "Content-Security-Policy", ContentSecurityPolicyBuilder.create().build()),
CONTENT_SECURITY_POLICY_REPORT_ONLY("contentSecurityPolicyReportOnly", "Content-Security-Policy-Report-Only", ""),
X_CONTENT_TYPE_OPTIONS("xContentTypeOptions", "X-Content-Type-Options", "nosniff"),
X_ROBOTS_TAG("xRobotsTag", "X-Robots-Tag", "none"),
X_XSS_PROTECTION("xXSSProtection", "X-XSS-Protection", "1; mode=block"),
STRICT_TRANSPORT_SECURITY("strictTransportSecurity", "Strict-Transport-Security", "max-age=31536000; includeSubDomains"),
REFERRER_POLICY("referrerPolicy", "Referrer-Policy", "no-referrer"),
;
public static final String X_FRAME_OPTIONS_DEFAULT = "SAMEORIGIN"; private final String key;
private final String headerName;
private final String defaultValue;
public static final String X_FRAME_OPTIONS_KEY = "xFrameOptions"; BrowserSecurityHeaders(String key, String headerName, String defaultValue) {
this.key = key;
this.headerName = headerName;
this.defaultValue = defaultValue;
}
public static final String CONTENT_SECURITY_POLICY = "Content-Security-Policy"; public String getKey() {
return key;
}
public static final String CONTENT_SECURITY_POLICY_DEFAULT = ContentSecurityPolicyBuilder.create().build(); public String getHeaderName() {
return headerName;
}
public static final String CONTENT_SECURITY_POLICY_KEY = "contentSecurityPolicy"; public String getDefaultValue() {
return defaultValue;
}
public static final String CONTENT_SECURITY_POLICY_REPORT_ONLY = "Content-Security-Policy-Report-Only"; @Deprecated // should be removed eventually
public static final Map<String, String> realmDefaultHeaders;
public static final String CONTENT_SECURITY_POLICY_REPORT_ONLY_DEFAULT = "";
public static final String CONTENT_SECURITY_POLICY_REPORT_ONLY_KEY = "contentSecurityPolicyReportOnly";
public static final String X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options";
public static final String X_CONTENT_TYPE_OPTIONS_DEFAULT = "nosniff";
public static final String X_CONTENT_TYPE_OPTIONS_KEY = "xContentTypeOptions";
public static final String X_ROBOTS_TAG = "X-Robots-Tag";
public static final String X_ROBOTS_TAG_KEY = "xRobotsTag";
public static final String X_ROBOTS_TAG_DEFAULT = "none";
public static final String X_XSS_PROTECTION = "X-XSS-Protection";
public static final String X_XSS_PROTECTION_DEFAULT = "1; mode=block";
public static final String X_XSS_PROTECTION_KEY = "xXSSProtection";
public static final String STRICT_TRANSPORT_SECURITY = "Strict-Transport-Security";
public static final String STRICT_TRANSPORT_SECURITY_DEFAULT = "max-age=31536000; includeSubDomains";
public static final String STRICT_TRANSPORT_SECURITY_KEY = "strictTransportSecurity";
public static final Map<String, String> headerAttributeMap;
public static final Map<String, String> defaultHeaders;
static { static {
Map<String, String> headerMap = new HashMap<>();
headerMap.put(X_FRAME_OPTIONS_KEY, X_FRAME_OPTIONS);
headerMap.put(CONTENT_SECURITY_POLICY_KEY, CONTENT_SECURITY_POLICY);
headerMap.put(CONTENT_SECURITY_POLICY_REPORT_ONLY_KEY, CONTENT_SECURITY_POLICY_REPORT_ONLY);
headerMap.put(X_CONTENT_TYPE_OPTIONS_KEY, X_CONTENT_TYPE_OPTIONS);
headerMap.put(X_ROBOTS_TAG_KEY, X_ROBOTS_TAG);
headerMap.put(X_XSS_PROTECTION_KEY, X_XSS_PROTECTION);
headerMap.put(STRICT_TRANSPORT_SECURITY_KEY, STRICT_TRANSPORT_SECURITY);
Map<String, String> dh = new HashMap<>(); Map<String, String> dh = new HashMap<>();
dh.put(X_FRAME_OPTIONS_KEY, X_FRAME_OPTIONS_DEFAULT); dh.put(X_FRAME_OPTIONS.getKey(), X_FRAME_OPTIONS.getDefaultValue());
dh.put(CONTENT_SECURITY_POLICY_KEY, CONTENT_SECURITY_POLICY_DEFAULT); dh.put(CONTENT_SECURITY_POLICY.getKey(), CONTENT_SECURITY_POLICY.getDefaultValue());
dh.put(CONTENT_SECURITY_POLICY_REPORT_ONLY_KEY, CONTENT_SECURITY_POLICY_REPORT_ONLY_DEFAULT); dh.put(CONTENT_SECURITY_POLICY_REPORT_ONLY.getKey(), CONTENT_SECURITY_POLICY_REPORT_ONLY.getDefaultValue());
dh.put(X_CONTENT_TYPE_OPTIONS_KEY, X_CONTENT_TYPE_OPTIONS_DEFAULT); dh.put(X_CONTENT_TYPE_OPTIONS.getKey(), X_CONTENT_TYPE_OPTIONS.getDefaultValue());
dh.put(X_ROBOTS_TAG_KEY, X_ROBOTS_TAG_DEFAULT); dh.put(X_ROBOTS_TAG.getKey(), X_ROBOTS_TAG.getDefaultValue());
dh.put(X_XSS_PROTECTION_KEY, X_XSS_PROTECTION_DEFAULT); dh.put(X_XSS_PROTECTION.getKey(), X_XSS_PROTECTION.getDefaultValue());
dh.put(STRICT_TRANSPORT_SECURITY_KEY, STRICT_TRANSPORT_SECURITY_DEFAULT); dh.put(STRICT_TRANSPORT_SECURITY.getKey(), STRICT_TRANSPORT_SECURITY.getDefaultValue());
defaultHeaders = Collections.unmodifiableMap(dh); realmDefaultHeaders = Collections.unmodifiableMap(dh);
headerAttributeMap = Collections.unmodifiableMap(headerMap);
} }
public static class ContentSecurityPolicyBuilder {
private String frameSrc = "'self'";
private String frameAncestors = "'self'";
private String objectSrc = "'none'";
private boolean first;
private StringBuilder sb;
public static ContentSecurityPolicyBuilder create() {
return new ContentSecurityPolicyBuilder();
}
public ContentSecurityPolicyBuilder frameSrc(String frameSrc) {
this.frameSrc = frameSrc;
return this;
}
public ContentSecurityPolicyBuilder frameAncestors(String frameancestors) {
this.frameAncestors = frameancestors;
return this;
}
public String build() {
sb = new StringBuilder();
first = true;
build("frame-src", frameSrc);
build("frame-ancestors", frameAncestors);
build("object-src", objectSrc);
return sb.toString();
}
private void build(String k, String v) {
if (v != null) {
if (!first) {
sb.append(" ");
}
first = false;
sb.append(k).append(" ").append(v).append(";");
}
}
}
} }

View file

@ -0,0 +1,48 @@
package org.keycloak.models;
public class ContentSecurityPolicyBuilder {
private String frameSrc = "'self'";
private String frameAncestors = "'self'";
private String objectSrc = "'none'";
private boolean first;
private StringBuilder sb;
public static ContentSecurityPolicyBuilder create() {
return new ContentSecurityPolicyBuilder();
}
public ContentSecurityPolicyBuilder frameSrc(String frameSrc) {
this.frameSrc = frameSrc;
return this;
}
public ContentSecurityPolicyBuilder frameAncestors(String frameancestors) {
this.frameAncestors = frameancestors;
return this;
}
public String build() {
sb = new StringBuilder();
first = true;
build("frame-src", frameSrc);
build("frame-ancestors", frameAncestors);
build("object-src", objectSrc);
return sb.toString();
}
private void build(String k, String v) {
if (v != null) {
if (!first) {
sb.append(" ");
}
first = false;
sb.append(k).append(" ").append(v).append(";");
}
}
}

View file

@ -387,7 +387,7 @@ public class RepresentationToModel {
if (rep.getBrowserSecurityHeaders() != null) { if (rep.getBrowserSecurityHeaders() != null) {
newRealm.setBrowserSecurityHeaders(rep.getBrowserSecurityHeaders()); newRealm.setBrowserSecurityHeaders(rep.getBrowserSecurityHeaders());
} else { } else {
newRealm.setBrowserSecurityHeaders(BrowserSecurityHeaders.defaultHeaders); newRealm.setBrowserSecurityHeaders(BrowserSecurityHeaders.realmDefaultHeaders);
} }
if (rep.getComponents() != null) { if (rep.getComponents() != null) {

View file

@ -8,10 +8,10 @@ public class BrowserSecurityHeadersTest {
@Test @Test
public void contentSecurityPolicyBuilderTest() { public void contentSecurityPolicyBuilderTest() {
assertEquals("frame-src 'self'; frame-ancestors 'self'; object-src 'none';", BrowserSecurityHeaders.ContentSecurityPolicyBuilder.create().build()); assertEquals("frame-src 'self'; frame-ancestors 'self'; object-src 'none';", ContentSecurityPolicyBuilder.create().build());
assertEquals("frame-ancestors 'self'; object-src 'none';", BrowserSecurityHeaders.ContentSecurityPolicyBuilder.create().frameSrc(null).build()); assertEquals("frame-ancestors 'self'; object-src 'none';", ContentSecurityPolicyBuilder.create().frameSrc(null).build());
assertEquals("frame-src 'self'; object-src 'none';", BrowserSecurityHeaders.ContentSecurityPolicyBuilder.create().frameAncestors(null).build()); assertEquals("frame-src 'self'; object-src 'none';", 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';", ContentSecurityPolicyBuilder.create().frameSrc("'custom-frame-src'").frameAncestors("'custom-frame-ancestors'").build());
} }
} }

View file

@ -18,6 +18,7 @@ package org.keycloak.headers;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.models.BrowserSecurityHeaders; import org.keycloak.models.BrowserSecurityHeaders;
import org.keycloak.models.ContentSecurityPolicyBuilder;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
@ -26,8 +27,11 @@ import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.MultivaluedMap;
import java.util.Collections;
import java.util.Map; import java.util.Map;
import static org.keycloak.models.BrowserSecurityHeaders.CONTENT_SECURITY_POLICY;
public class DefaultSecurityHeadersProvider implements SecurityHeadersProvider { public class DefaultSecurityHeadersProvider implements SecurityHeadersProvider {
private static final Logger LOGGER = Logger.getLogger(DefaultSecurityHeadersProvider.class); private static final Logger LOGGER = Logger.getLogger(DefaultSecurityHeadersProvider.class);
@ -44,7 +48,7 @@ public class DefaultSecurityHeadersProvider implements SecurityHeadersProvider {
if (realm != null) { if (realm != null) {
headerValues = realm.getBrowserSecurityHeaders(); headerValues = realm.getBrowserSecurityHeaders();
} else { } else {
headerValues = BrowserSecurityHeaders.defaultHeaders; headerValues = Collections.emptyMap();
} }
} }
@ -81,27 +85,31 @@ public class DefaultSecurityHeadersProvider implements SecurityHeadersProvider {
} }
private void addGenericHeaders(MultivaluedMap<String, Object> headers) { private void addGenericHeaders(MultivaluedMap<String, Object> headers) {
addHeader(BrowserSecurityHeaders.STRICT_TRANSPORT_SECURITY_KEY, headers); addHeader(BrowserSecurityHeaders.STRICT_TRANSPORT_SECURITY, headers);
addHeader(BrowserSecurityHeaders.X_CONTENT_TYPE_OPTIONS_KEY, headers); addHeader(BrowserSecurityHeaders.X_CONTENT_TYPE_OPTIONS, headers);
addHeader(BrowserSecurityHeaders.X_XSS_PROTECTION_KEY, headers); addHeader(BrowserSecurityHeaders.X_XSS_PROTECTION, headers);
addHeader(BrowserSecurityHeaders.REFERRER_POLICY, headers);
} }
private void addRestHeaders(MultivaluedMap<String, Object> headers) { private void addRestHeaders(MultivaluedMap<String, Object> headers) {
addHeader(BrowserSecurityHeaders.STRICT_TRANSPORT_SECURITY_KEY, headers); addHeader(BrowserSecurityHeaders.STRICT_TRANSPORT_SECURITY, headers);
addHeader(BrowserSecurityHeaders.X_FRAME_OPTIONS_KEY, headers); addHeader(BrowserSecurityHeaders.X_FRAME_OPTIONS, headers);
addHeader(BrowserSecurityHeaders.X_CONTENT_TYPE_OPTIONS_KEY, headers); addHeader(BrowserSecurityHeaders.X_CONTENT_TYPE_OPTIONS, headers);
addHeader(BrowserSecurityHeaders.X_XSS_PROTECTION_KEY, headers); addHeader(BrowserSecurityHeaders.X_XSS_PROTECTION, headers);
addHeader(BrowserSecurityHeaders.REFERRER_POLICY, headers);
} }
private void addHtmlHeaders(MultivaluedMap<String, Object> headers) { private void addHtmlHeaders(MultivaluedMap<String, Object> headers) {
BrowserSecurityHeaders.headerAttributeMap.keySet().forEach(k -> addHeader(k, headers)); for (BrowserSecurityHeaders header : BrowserSecurityHeaders.values()) {
addHeader(header, headers);
}
// TODO This will be refactored as part of introducing a more strict CSP header // TODO This will be refactored as part of introducing a more strict CSP header
if (options != null) { if (options != null) {
BrowserSecurityHeaders.ContentSecurityPolicyBuilder csp = BrowserSecurityHeaders.ContentSecurityPolicyBuilder.create(); ContentSecurityPolicyBuilder csp = ContentSecurityPolicyBuilder.create();
if (options.isAllowAnyFrameAncestor()) { if (options.isAllowAnyFrameAncestor()) {
headers.remove(BrowserSecurityHeaders.X_FRAME_OPTIONS); headers.remove(BrowserSecurityHeaders.X_FRAME_OPTIONS.getHeaderName());
csp.frameAncestors(null); csp.frameAncestors(null);
} }
@ -111,17 +119,16 @@ public class DefaultSecurityHeadersProvider implements SecurityHeadersProvider {
csp.frameSrc(allowedFrameSrc); csp.frameSrc(allowedFrameSrc);
} }
if (BrowserSecurityHeaders.CONTENT_SECURITY_POLICY_DEFAULT.equals(headers.getFirst(BrowserSecurityHeaders.CONTENT_SECURITY_POLICY))) { if (CONTENT_SECURITY_POLICY.getDefaultValue().equals(headers.getFirst(CONTENT_SECURITY_POLICY.getHeaderName()))) {
headers.putSingle(BrowserSecurityHeaders.CONTENT_SECURITY_POLICY, csp.build()); headers.putSingle(CONTENT_SECURITY_POLICY.getHeaderName(), csp.build());
} }
} }
} }
private void addHeader(String key, MultivaluedMap<String, Object> headers) { private void addHeader(BrowserSecurityHeaders header, MultivaluedMap<String, Object> headers) {
String header = BrowserSecurityHeaders.headerAttributeMap.get(key); String value = headerValues.getOrDefault(header.getKey(), header.getDefaultValue());
String value = headerValues.get(key);
if (value != null && !value.isEmpty()) { if (value != null && !value.isEmpty()) {
headers.putSingle(header, value); headers.putSingle(header.getHeaderName(), value);
} }
} }

View file

@ -227,7 +227,7 @@ public class RealmManager {
protected void setupRealmDefaults(RealmModel realm) { protected void setupRealmDefaults(RealmModel realm) {
realm.setBrowserSecurityHeaders(BrowserSecurityHeaders.defaultHeaders); realm.setBrowserSecurityHeaders(BrowserSecurityHeaders.realmDefaultHeaders);
// brute force // brute force
realm.setBruteForceProtected(false); // default settings off for now todo set it on realm.setBruteForceProtected(false); // default settings off for now todo set it on

View file

@ -1,22 +1,20 @@
package org.keycloak.testsuite.admin; package org.keycloak.testsuite.admin;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClientBuilder;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.keycloak.models.BrowserSecurityHeaders; import org.keycloak.models.BrowserSecurityHeaders;
import org.keycloak.services.resources.Cors;
import org.keycloak.testsuite.util.UserBuilder; import org.keycloak.testsuite.util.UserBuilder;
import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.io.IOException; import java.io.IOException;
import static org.junit.Assert.assertEquals; import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertTrue; import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
public class AdminHeadersTest extends AbstractAdminTest { public class AdminHeadersTest extends AbstractAdminTest {
@ -42,14 +40,19 @@ public class AdminHeadersTest extends AbstractAdminTest {
Response response = realm.users().create(UserBuilder.create().username("headers-user").build()); Response response = realm.users().create(UserBuilder.create().username("headers-user").build());
MultivaluedMap<String, Object> h = response.getHeaders(); MultivaluedMap<String, Object> h = response.getHeaders();
assertEquals(BrowserSecurityHeaders.STRICT_TRANSPORT_SECURITY_DEFAULT, h.getFirst(BrowserSecurityHeaders.STRICT_TRANSPORT_SECURITY)); assertDefaultValue(BrowserSecurityHeaders.STRICT_TRANSPORT_SECURITY, h);
assertEquals(BrowserSecurityHeaders.X_FRAME_OPTIONS_DEFAULT, h.getFirst(BrowserSecurityHeaders.X_FRAME_OPTIONS)); assertDefaultValue(BrowserSecurityHeaders.X_FRAME_OPTIONS, h);
assertEquals(BrowserSecurityHeaders.X_CONTENT_TYPE_OPTIONS_DEFAULT, h.getFirst(BrowserSecurityHeaders.X_CONTENT_TYPE_OPTIONS)); assertDefaultValue(BrowserSecurityHeaders.X_CONTENT_TYPE_OPTIONS, h);
assertEquals(BrowserSecurityHeaders.X_XSS_PROTECTION_DEFAULT, h.getFirst(BrowserSecurityHeaders.X_XSS_PROTECTION)); assertDefaultValue(BrowserSecurityHeaders.X_XSS_PROTECTION, h);
assertDefaultValue(BrowserSecurityHeaders.REFERRER_POLICY, h);
response.close(); response.close();
} }
private void assertDefaultValue(BrowserSecurityHeaders header, MultivaluedMap<String, Object> h) {
assertThat(h.getFirst(header.getHeaderName()), is(equalTo(header.getDefaultValue())));
}
private String getAdminUrl(String resource) { private String getAdminUrl(String resource) {
return suiteContext.getAuthServerInfo().getContextRoot().toString() + "/auth/admin/" + resource; return suiteContext.getAuthServerInfo().getContextRoot().toString() + "/auth/admin/" + resource;
} }

View file

@ -1,9 +1,7 @@
package org.keycloak.testsuite.error; package org.keycloak.testsuite.error;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClientBuilder;
@ -14,7 +12,6 @@ import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.broker.provider.util.SimpleHttp; import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.common.util.StreamUtil; import org.keycloak.common.util.StreamUtil;
import org.keycloak.models.BrowserSecurityHeaders; import org.keycloak.models.BrowserSecurityHeaders;
import org.keycloak.representations.idm.ErrorRepresentation;
import org.keycloak.representations.idm.OAuth2ErrorRepresentation; import org.keycloak.representations.idm.OAuth2ErrorRepresentation;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AbstractKeycloakTest;
@ -31,7 +28,6 @@ import java.net.URI;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@ -126,14 +122,13 @@ public class UncaughtErrorPageTest extends AbstractKeycloakTest {
try (CloseableHttpClient client = HttpClientBuilder.create().build()) { try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
SimpleHttp.Response response = SimpleHttp.doGet(uri.toString(), client).header("Accept", MediaType.TEXT_HTML_UTF_8).asResponse(); SimpleHttp.Response response = SimpleHttp.doGet(uri.toString(), client).header("Accept", MediaType.TEXT_HTML_UTF_8).asResponse();
for (Map.Entry<String, String> e : BrowserSecurityHeaders.headerAttributeMap.entrySet()) { for (BrowserSecurityHeaders header : BrowserSecurityHeaders.values()) {
String header = e.getValue(); String expectedValue = header.getDefaultValue();
String expectedValue = BrowserSecurityHeaders.defaultHeaders.get(e.getKey());
if (expectedValue == null || expectedValue.isEmpty()) { if (expectedValue == null || expectedValue.isEmpty()) {
assertNull(response.getFirstHeader(header)); assertNull(response.getFirstHeader(header.getHeaderName()));
} else { } else {
assertEquals(expectedValue, response.getFirstHeader(header)); assertEquals(expectedValue, response.getFirstHeader(header.getHeaderName()));
} }
} }
} }

View file

@ -68,7 +68,6 @@ import javax.ws.rs.core.UriBuilder;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
@ -164,14 +163,14 @@ public class LoginTest extends AbstractTestRealmKeycloakTest {
Client client = ClientBuilder.newClient(); Client client = ClientBuilder.newClient();
Response response = client.target(oauth.getLoginFormUrl()).request().get(); Response response = client.target(oauth.getLoginFormUrl()).request().get();
Assert.assertThat(response.getStatus(), is(equalTo(200))); Assert.assertThat(response.getStatus(), is(equalTo(200)));
for (Map.Entry<String, String> entry : BrowserSecurityHeaders.defaultHeaders.entrySet()) { for (BrowserSecurityHeaders header : BrowserSecurityHeaders.values()) {
String headerName = BrowserSecurityHeaders.headerAttributeMap.get(entry.getKey()); String headerValue = response.getHeaderString(header.getHeaderName());
String headerValue = response.getHeaderString(headerName); String expectedValue = header.getDefaultValue();
if (entry.getValue().isEmpty()) { if (expectedValue.isEmpty()) {
Assert.assertNull(headerValue); Assert.assertNull(headerValue);
} else { } else {
Assert.assertNotNull(headerValue); Assert.assertNotNull(headerValue);
Assert.assertThat(headerValue, is(equalTo(entry.getValue()))); Assert.assertThat(headerValue, is(equalTo(expectedValue)));
} }
} }
response.close(); response.close();

View file

@ -130,9 +130,9 @@ public class LoginStatusIframeEndpointTest extends AbstractKeycloakTest {
assertTrue(s.contains("function getCookie()")); assertTrue(s.contains("function getCookie()"));
assertEquals("CP=\"This is not a P3P policy!\"", response.getFirstHeader("P3P").getValue()); assertEquals("CP=\"This is not a P3P policy!\"", response.getFirstHeader("P3P").getValue());
assertNull(response.getFirstHeader(BrowserSecurityHeaders.X_FRAME_OPTIONS)); assertNull(response.getFirstHeader(BrowserSecurityHeaders.X_FRAME_OPTIONS.getHeaderName()));
assertEquals("frame-src 'self'; object-src 'none';", response.getFirstHeader(BrowserSecurityHeaders.CONTENT_SECURITY_POLICY).getValue()); assertEquals("frame-src 'self'; object-src 'none';", response.getFirstHeader(BrowserSecurityHeaders.CONTENT_SECURITY_POLICY.getHeaderName()).getValue());
assertEquals("none", response.getFirstHeader(BrowserSecurityHeaders.X_ROBOTS_TAG).getValue()); assertEquals("none", response.getFirstHeader(BrowserSecurityHeaders.X_ROBOTS_TAG.getHeaderName()).getValue());
response.close(); response.close();

View file

@ -255,7 +255,7 @@ public class DefaultHostnameTest extends AbstractHostnameTest {
assertTrue(indexPage.contains("consoleBaseUrl = '" + new URI(expectedAdminUrl).getPath() +"/admin/" + realm + "/console/'")); assertTrue(indexPage.contains("consoleBaseUrl = '" + new URI(expectedAdminUrl).getPath() +"/admin/" + realm + "/console/'"));
assertTrue(indexPage.contains("resourceUrl = '" + new URI(expectedAdminUrl).getPath() +"/resources/")); assertTrue(indexPage.contains("resourceUrl = '" + new URI(expectedAdminUrl).getPath() +"/resources/"));
String cspHeader = response.getFirstHeader(BrowserSecurityHeaders.CONTENT_SECURITY_POLICY); String cspHeader = response.getFirstHeader(BrowserSecurityHeaders.CONTENT_SECURITY_POLICY.getHeaderName());
if (expectedFrontendUrl.equalsIgnoreCase(expectedAdminUrl)) { if (expectedFrontendUrl.equalsIgnoreCase(expectedAdminUrl)) {
assertEquals("frame-src 'self'; frame-ancestors 'self'; object-src 'none';", cspHeader); assertEquals("frame-src 'self'; frame-ancestors 'self'; object-src 'none';", cspHeader);