|
@@ -1,5 +1,5 @@
|
|
/*
|
|
/*
|
|
- * Copyright 2002-2019 the original author or authors.
|
|
|
|
|
|
+ * Copyright 2002-2022 the original author or authors.
|
|
*
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* you may not use this file except in compliance with the License.
|
|
@@ -20,6 +20,7 @@ import jakarta.servlet.http.HttpServletRequest;
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
|
|
|
|
import org.springframework.security.web.header.HeaderWriter;
|
|
import org.springframework.security.web.header.HeaderWriter;
|
|
|
|
+import org.springframework.util.Assert;
|
|
|
|
|
|
/**
|
|
/**
|
|
* Renders the <a href=
|
|
* Renders the <a href=
|
|
@@ -34,25 +35,19 @@ public final class XXssProtectionHeaderWriter implements HeaderWriter {
|
|
|
|
|
|
private static final String XSS_PROTECTION_HEADER = "X-XSS-Protection";
|
|
private static final String XSS_PROTECTION_HEADER = "X-XSS-Protection";
|
|
|
|
|
|
- private boolean enabled;
|
|
|
|
-
|
|
|
|
- private boolean block;
|
|
|
|
-
|
|
|
|
- private String headerValue;
|
|
|
|
|
|
+ private HeaderValue headerValue;
|
|
|
|
|
|
/**
|
|
/**
|
|
* Create a new instance
|
|
* Create a new instance
|
|
*/
|
|
*/
|
|
public XXssProtectionHeaderWriter() {
|
|
public XXssProtectionHeaderWriter() {
|
|
- this.enabled = true;
|
|
|
|
- this.block = true;
|
|
|
|
- updateHeaderValue();
|
|
|
|
|
|
+ this.headerValue = HeaderValue.ENABLED_MODE_BLOCK;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
|
|
public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
|
|
if (!response.containsHeader(XSS_PROTECTION_HEADER)) {
|
|
if (!response.containsHeader(XSS_PROTECTION_HEADER)) {
|
|
- response.setHeader(XSS_PROTECTION_HEADER, this.headerValue);
|
|
|
|
|
|
+ response.setHeader(XSS_PROTECTION_HEADER, this.headerValue.toString());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -77,37 +72,88 @@ public final class XXssProtectionHeaderWriter implements HeaderWriter {
|
|
* X-XSS-Protection: 0
|
|
* X-XSS-Protection: 0
|
|
* </pre>
|
|
* </pre>
|
|
* @param enabled the new value
|
|
* @param enabled the new value
|
|
|
|
+ * @deprecated use {@link XXssProtectionHeaderWriter#setHeaderValue(HeaderValue)}
|
|
|
|
+ * instead
|
|
*/
|
|
*/
|
|
|
|
+ @Deprecated
|
|
public void setEnabled(boolean enabled) {
|
|
public void setEnabled(boolean enabled) {
|
|
if (!enabled) {
|
|
if (!enabled) {
|
|
- setBlock(false);
|
|
|
|
|
|
+ this.headerValue = HeaderValue.DISABLED;
|
|
|
|
+ }
|
|
|
|
+ else if (this.headerValue == HeaderValue.DISABLED) {
|
|
|
|
+ this.headerValue = HeaderValue.ENABLED;
|
|
}
|
|
}
|
|
- this.enabled = enabled;
|
|
|
|
- updateHeaderValue();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* If false, will not specify the mode as blocked. In this instance, any content will
|
|
* If false, will not specify the mode as blocked. In this instance, any content will
|
|
* be attempted to be fixed. If true, the content will be replaced with "#".
|
|
* be attempted to be fixed. If true, the content will be replaced with "#".
|
|
* @param block the new value
|
|
* @param block the new value
|
|
|
|
+ * @deprecated use {@link XXssProtectionHeaderWriter#setHeaderValue(HeaderValue)}
|
|
|
|
+ * instead
|
|
*/
|
|
*/
|
|
|
|
+ @Deprecated
|
|
public void setBlock(boolean block) {
|
|
public void setBlock(boolean block) {
|
|
- if (!this.enabled && block) {
|
|
|
|
|
|
+ if (this.headerValue == HeaderValue.DISABLED && block) {
|
|
throw new IllegalArgumentException("Cannot set block to true with enabled false");
|
|
throw new IllegalArgumentException("Cannot set block to true with enabled false");
|
|
}
|
|
}
|
|
- this.block = block;
|
|
|
|
- updateHeaderValue();
|
|
|
|
|
|
+ this.headerValue = block ? HeaderValue.ENABLED_MODE_BLOCK : HeaderValue.ENABLED;
|
|
}
|
|
}
|
|
|
|
|
|
- private void updateHeaderValue() {
|
|
|
|
- if (!this.enabled) {
|
|
|
|
- this.headerValue = "0";
|
|
|
|
- return;
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Sets the value of the X-XSS-PROTECTION header.
|
|
|
|
+ * <p>
|
|
|
|
+ * If {@link HeaderValue#DISABLED}, will specify that X-XSS-Protection is disabled.
|
|
|
|
+ * For example:
|
|
|
|
+ *
|
|
|
|
+ * <pre>
|
|
|
|
+ * X-XSS-Protection: 0
|
|
|
|
+ * </pre>
|
|
|
|
+ * <p>
|
|
|
|
+ * If {@link HeaderValue#ENABLED}, will contain a value of 1, but will not specify the
|
|
|
|
+ * mode as blocked. In this instance, any content will be attempted to be fixed. For
|
|
|
|
+ * example:
|
|
|
|
+ *
|
|
|
|
+ * <pre>
|
|
|
|
+ * X-XSS-Protection: 1
|
|
|
|
+ * </pre>
|
|
|
|
+ * <p>
|
|
|
|
+ * If {@link HeaderValue#ENABLED_MODE_BLOCK}, will contain a value of 1 and will
|
|
|
|
+ * specify mode as blocked. The content will be replaced with "#". For example:
|
|
|
|
+ *
|
|
|
|
+ * <pre>
|
|
|
|
+ * X-XSS-Protection: 1 ; mode=block
|
|
|
|
+ * </pre>
|
|
|
|
+ * @param headerValue the new header value
|
|
|
|
+ * @throws IllegalArgumentException when headerValue is null
|
|
|
|
+ * @since 5.8
|
|
|
|
+ */
|
|
|
|
+ public void setHeaderValue(HeaderValue headerValue) {
|
|
|
|
+ Assert.notNull(headerValue, "headerValue cannot be null");
|
|
|
|
+ this.headerValue = headerValue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * The value of the x-xss-protection header. One of: "0", "1", "1 ; mode=block"
|
|
|
|
+ *
|
|
|
|
+ * @author Daniel Garnier-Moiroux
|
|
|
|
+ * @since 5.8
|
|
|
|
+ */
|
|
|
|
+ public enum HeaderValue {
|
|
|
|
+
|
|
|
|
+ DISABLED("0"), ENABLED("1"), ENABLED_MODE_BLOCK("1; mode=block");
|
|
|
|
+
|
|
|
|
+ private final String value;
|
|
|
|
+
|
|
|
|
+ HeaderValue(String value) {
|
|
|
|
+ this.value = value;
|
|
}
|
|
}
|
|
- this.headerValue = "1";
|
|
|
|
- if (this.block) {
|
|
|
|
- this.headerValue += "; mode=block";
|
|
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public String toString() {
|
|
|
|
+ return this.value;
|
|
}
|
|
}
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|