Spencer Gibb
8 years ago
6 changed files with 221 additions and 11 deletions
@ -0,0 +1,106 @@
@@ -0,0 +1,106 @@
|
||||
package org.springframework.cloud.gateway.filter.route; |
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
||||
/** |
||||
* @author Spencer Gibb |
||||
*/ |
||||
@ConfigurationProperties("spring.cloud.gateway.filter.secureHeaders") |
||||
public class SecureHeadersProperties { |
||||
public static final String X_XSS_PROTECTION_HEADER_DEFAULT = "1; mode=block"; |
||||
public static final String STRICT_TRANSPORT_SECURITY_HEADER_DEFAULT = "max-age=631138519"; //; includeSubDomains preload")
|
||||
public static final String X_FRAME_OPTIONS_HEADER_DEFAULT = "DENY"; //SAMEORIGIN = ALLOW-FROM
|
||||
public static final String X_CONTENT_TYPE_OPTIONS_HEADER_DEFAULT = "nosniff"; |
||||
public static final String REFERRER_POLICY_HEADER_DEFAULT = "no-referrer"; //no-referrer-when-downgrade = origin = origin-when-cross-origin = same-origin = strict-origin = strict-origin-when-cross-origin = unsafe-url
|
||||
public static final String CONTENT_SECURITY_POLICY_HEADER_DEFAULT = "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'"; |
||||
public static final String X_DOWNLOAD_OPTIONS_HEADER_DEFAULT = "noopen"; |
||||
public static final String X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER_DEFAULT = "none"; |
||||
|
||||
private String xssProtectionHeader = X_XSS_PROTECTION_HEADER_DEFAULT; |
||||
private String strictTransportSecurity = STRICT_TRANSPORT_SECURITY_HEADER_DEFAULT; |
||||
private String frameOptions = X_FRAME_OPTIONS_HEADER_DEFAULT; |
||||
private String contentTypeOptions = X_CONTENT_TYPE_OPTIONS_HEADER_DEFAULT; |
||||
private String referrerPolicy = REFERRER_POLICY_HEADER_DEFAULT; |
||||
private String contentSecurityPolicy = CONTENT_SECURITY_POLICY_HEADER_DEFAULT; |
||||
private String downloadOptions = X_DOWNLOAD_OPTIONS_HEADER_DEFAULT; |
||||
private String permittedCrossDomainPolicies = X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER_DEFAULT; |
||||
|
||||
public String getXssProtectionHeader() { |
||||
return xssProtectionHeader; |
||||
} |
||||
|
||||
public void setXssProtectionHeader(String xssProtectionHeader) { |
||||
this.xssProtectionHeader = xssProtectionHeader; |
||||
} |
||||
|
||||
public String getStrictTransportSecurity() { |
||||
return strictTransportSecurity; |
||||
} |
||||
|
||||
public void setStrictTransportSecurity(String strictTransportSecurity) { |
||||
this.strictTransportSecurity = strictTransportSecurity; |
||||
} |
||||
|
||||
public String getFrameOptions() { |
||||
return frameOptions; |
||||
} |
||||
|
||||
public void setFrameOptions(String frameOptions) { |
||||
this.frameOptions = frameOptions; |
||||
} |
||||
|
||||
public String getContentTypeOptions() { |
||||
return contentTypeOptions; |
||||
} |
||||
|
||||
public void setContentTypeOptions(String contentTypeOptions) { |
||||
this.contentTypeOptions = contentTypeOptions; |
||||
} |
||||
|
||||
public String getReferrerPolicy() { |
||||
return referrerPolicy; |
||||
} |
||||
|
||||
public void setReferrerPolicy(String referrerPolicy) { |
||||
this.referrerPolicy = referrerPolicy; |
||||
} |
||||
|
||||
public String getContentSecurityPolicy() { |
||||
return contentSecurityPolicy; |
||||
} |
||||
|
||||
public void setContentSecurityPolicy(String contentSecurityPolicy) { |
||||
this.contentSecurityPolicy = contentSecurityPolicy; |
||||
} |
||||
|
||||
public String getDownloadOptions() { |
||||
return downloadOptions; |
||||
} |
||||
|
||||
public void setDownloadOptions(String downloadOptions) { |
||||
this.downloadOptions = downloadOptions; |
||||
} |
||||
|
||||
public String getPermittedCrossDomainPolicies() { |
||||
return permittedCrossDomainPolicies; |
||||
} |
||||
|
||||
public void setPermittedCrossDomainPolicies(String permittedCrossDomainPolicies) { |
||||
this.permittedCrossDomainPolicies = permittedCrossDomainPolicies; |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
final StringBuffer sb = new StringBuffer("SecureHeadersProperties{"); |
||||
sb.append("xssProtectionHeader='").append(xssProtectionHeader).append('\''); |
||||
sb.append(", strictTransportSecurity='").append(strictTransportSecurity).append('\''); |
||||
sb.append(", frameOptions='").append(frameOptions).append('\''); |
||||
sb.append(", contentTypeOptions='").append(contentTypeOptions).append('\''); |
||||
sb.append(", referrerPolicy='").append(referrerPolicy).append('\''); |
||||
sb.append(", contentSecurityPolicy='").append(contentSecurityPolicy).append('\''); |
||||
sb.append(", downloadOptions='").append(downloadOptions).append('\''); |
||||
sb.append(", permittedCrossDomainPolicies='").append(permittedCrossDomainPolicies).append('\''); |
||||
sb.append('}'); |
||||
return sb.toString(); |
||||
} |
||||
} |
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
package org.springframework.cloud.gateway.filter.route; |
||||
|
||||
import org.springframework.http.HttpHeaders; |
||||
import org.springframework.web.server.WebFilter; |
||||
|
||||
/** |
||||
* https://blog.appcanary.com/2017/http-security-headers.html
|
||||
* @author Spencer Gibb |
||||
*/ |
||||
public class SecureHeadersRouteFilter implements RouteFilter { |
||||
|
||||
public static final String X_XSS_PROTECTION_HEADER = "X-Xss-Protection"; |
||||
public static final String STRICT_TRANSPORT_SECURITY_HEADER = "Strict-Transport-Security"; |
||||
public static final String X_FRAME_OPTIONS_HEADER = "X-Frame-Options"; |
||||
public static final String X_CONTENT_TYPE_OPTIONS_HEADER = "X-Content-Type-Options"; |
||||
public static final String REFERRER_POLICY_HEADER = "Referrer-Policy"; |
||||
public static final String CONTENT_SECURITY_POLICY_HEADER = "Content-Security-Policy"; |
||||
public static final String X_DOWNLOAD_OPTIONS_HEADER = "X-Download-Options"; |
||||
public static final String X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER = "X-Permitted-Cross-Domain-Policies"; |
||||
|
||||
private final SecureHeadersProperties properties; |
||||
|
||||
public SecureHeadersRouteFilter(SecureHeadersProperties properties) { |
||||
this.properties = properties; |
||||
} |
||||
|
||||
@Override |
||||
public WebFilter apply(String... args) { |
||||
//TODO: allow args to override properties
|
||||
|
||||
return (exchange, chain) -> { |
||||
HttpHeaders headers = exchange.getResponse().getHeaders(); |
||||
|
||||
headers.add(X_XSS_PROTECTION_HEADER, properties.getXssProtectionHeader()); |
||||
headers.add(STRICT_TRANSPORT_SECURITY_HEADER, properties.getStrictTransportSecurity()); |
||||
headers.add(X_FRAME_OPTIONS_HEADER, properties.getFrameOptions()); |
||||
headers.add(X_CONTENT_TYPE_OPTIONS_HEADER, properties.getContentTypeOptions()); |
||||
headers.add(REFERRER_POLICY_HEADER, properties.getReferrerPolicy()); |
||||
headers.add(CONTENT_SECURITY_POLICY_HEADER, properties.getContentSecurityPolicy()); |
||||
headers.add(X_DOWNLOAD_OPTIONS_HEADER, properties.getDownloadOptions()); |
||||
headers.add(X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER, properties.getPermittedCrossDomainPolicies()); |
||||
|
||||
return chain.filter(exchange); |
||||
}; |
||||
} |
||||
} |
Loading…
Reference in new issue