diff --git a/hetu-docs/en/admin/properties.md b/hetu-docs/en/admin/properties.md index dc368addb..b7e461061 100644 --- a/hetu-docs/en/admin/properties.md +++ b/hetu-docs/en/admin/properties.md @@ -29,6 +29,52 @@ This section describes the most important config properties that may be used to > > This property make exception stack trace which happen in openLooKeng visible or invisible. While it is set to be `true`, the stack trace is visible for all users. While it is set as default or `false`, the stack trace is invisible for all users. + +## http security headers properties + +### `http-header.content-security-policy` + +> - **Type:** `string` +> - **Default value:** `object-src 'none'` +> +> Property to set the http security header `content-security-policy` . + +### `http-header.referrer-policy` + +> - **Type:** `string` +> - **Default value:** `strict-origin-when-cross-origin` +> +> Property to set the http security header `referrer-policy`. + +### `http-header.x-content-type-options` + +> - **类型:** `string` +> - **Default value:** `nosniff` +> +> Property to set the http security header `content-security-policy` . + +### `http-header.x-frame-options` + +> - **Type:** `string` +> - **Default value:** `deny` +> +> Property to set the http security header `content-security-policy`. + +### `http-header.x-permitted-cross-domain-policies` + +> - **Type=:** `string` +> - **Default value:** `master-only` +> +> Property to set the http security header `x-permitted-cross-domain-policies` . + +### `http-header.x-xss-protection` + +> - **Type:** `string` +> - **Default value:** `1; mode=block` +> +> Property to set the http security header `http-header.x-xss-protection`. + + ## Memory Management Properties ### `query.max-memory-per-node` diff --git a/hetu-docs/zh/admin/properties.md b/hetu-docs/zh/admin/properties.md index 334a9a471..52f71fde7 100644 --- a/hetu-docs/zh/admin/properties.md +++ b/hetu-docs/zh/admin/properties.md @@ -27,6 +27,50 @@ > > 此属性控制系统是否能够在CLI、WEB UI等对外展示系统出现Exception时的代码调用栈. 当设置为`true`时对外展示给所有用户,设置为`false`或者采用默认设置,不展示给任何用户。 +## http 安全头部属性 + +### `http-header.content-security-policy` + +> - **类型:** `string` +> - **默认值:** `object-src 'none'` +> +> 此属性设置 `content-security-policy` 设置相关值。 + +### `http-header.referrer-policy` + +> - **类型:** `string` +> - **默认值:** `strict-origin-when-cross-origin` +> +> 此属性设置 `referrer-policy` 设置相关值。 + +### `http-header.x-content-type-options` + +> - **类型:** `string` +> - **默认值:** `nosniff` +> +> 此属性设置 `content-security-policy` 设置相关值。 + +### `http-header.x-frame-options` + +> - **类型:** `string` +> - **默认值:** `deny` +> +> 此属性设置 `content-security-policy` 设置相关值。 + +### `http-header.x-permitted-cross-domain-policies` + +> - **类型:** `string` +> - **默认值:** `master-only` +> +> 此属性设置 `x-permitted-cross-domain-policies` 设置相关值。 + +### `http-header.x-xss-protection` + +> - **类型:** `string` +> - **默认值:** `1; mode=block` +> +> 此属性设置 `http-header.x-xss-protection` 设置相关值。 + ## 内存管理属性 ### `query.max-memory-per-node` diff --git a/presto-client/src/main/java/io/prestosql/client/HttpSecurityHeadersConstants.java b/presto-client/src/main/java/io/prestosql/client/HttpSecurityHeadersConstants.java index 3084d1254..1d3621670 100644 --- a/presto-client/src/main/java/io/prestosql/client/HttpSecurityHeadersConstants.java +++ b/presto-client/src/main/java/io/prestosql/client/HttpSecurityHeadersConstants.java @@ -14,6 +14,9 @@ */ package io.prestosql.client; +/** + * default setting + */ public class HttpSecurityHeadersConstants { /** @@ -24,7 +27,7 @@ public class HttpSecurityHeadersConstants /** * Http security header: Content-Security-Policy */ - public static final String HTTP_SECURITY_CSP_VALUE = "default-src 'self'"; + public static final String HTTP_SECURITY_CSP_VALUE = "object-src 'none'"; /** * Http security header: Referrer-Policy diff --git a/presto-client/src/main/java/io/prestosql/client/StatementClientV1.java b/presto-client/src/main/java/io/prestosql/client/StatementClientV1.java index dd24a5745..331db0fc7 100644 --- a/presto-client/src/main/java/io/prestosql/client/StatementClientV1.java +++ b/presto-client/src/main/java/io/prestosql/client/StatementClientV1.java @@ -190,12 +190,48 @@ class StatementClientV1 builder.addHeader(PrestoHeaders.PRESTO_CLIENT_CAPABILITIES, clientCapabilities); // add security header - builder.addHeader(HTTP_SECURITY_CSP, HTTP_SECURITY_CSP_VALUE); - builder.addHeader(HTTP_SECURITY_RP, HTTP_SECURITY_RP_VALUE); - builder.addHeader(HTTP_SECURITY_XCTO, HTTP_SECURITY_XCTO_VALUE); - builder.addHeader(HTTP_SECURITY_XFO, HTTP_SECURITY_XFO_VALUE); - builder.addHeader(HTTP_SECURITY_XPCDP, HTTP_SECURITY_XPCDP_VALUE); - builder.addHeader(HTTP_SECURITY_XXP, HTTP_SECURITY_XXP_VALUE); + if (System.getProperty(HTTP_SECURITY_CSP) != null) { + builder.addHeader(HTTP_SECURITY_CSP, System.getProperty(HTTP_SECURITY_CSP)); + } + else { + builder.addHeader(HTTP_SECURITY_CSP, HTTP_SECURITY_CSP_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_RP) != null) { + builder.addHeader(HTTP_SECURITY_RP, System.getProperty(HTTP_SECURITY_RP)); + } + else { + builder.addHeader(HTTP_SECURITY_RP, HTTP_SECURITY_RP_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_XCTO) != null) { + builder.addHeader(HTTP_SECURITY_XCTO, System.getProperty(HTTP_SECURITY_XCTO)); + } + else { + builder.addHeader(HTTP_SECURITY_XCTO, HTTP_SECURITY_XCTO_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_XFO) != null) { + builder.addHeader(HTTP_SECURITY_XFO, System.getProperty(HTTP_SECURITY_XFO)); + } + else { + builder.addHeader(HTTP_SECURITY_XFO, HTTP_SECURITY_XFO_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_XPCDP) != null) { + builder.addHeader(HTTP_SECURITY_XPCDP, System.getProperty(HTTP_SECURITY_XPCDP)); + } + else { + builder.addHeader(HTTP_SECURITY_XPCDP, HTTP_SECURITY_XPCDP_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_XXP) != null) { + builder.addHeader(HTTP_SECURITY_XXP, System.getProperty(HTTP_SECURITY_XXP)); + } + else { + builder.addHeader(HTTP_SECURITY_XXP, HTTP_SECURITY_XXP_VALUE); + } + return builder.build(); } diff --git a/presto-client/src/main/java/io/prestosql/client/util/HttpUtil.java b/presto-client/src/main/java/io/prestosql/client/util/HttpUtil.java index 662b696b9..d9c979cce 100644 --- a/presto-client/src/main/java/io/prestosql/client/util/HttpUtil.java +++ b/presto-client/src/main/java/io/prestosql/client/util/HttpUtil.java @@ -178,12 +178,47 @@ public class HttpUtil .addHeader(USER_AGENT, USER_AGENT_VALUE); builder.addHeader(ACCEPT_ENCODING_HEADER, ""); // add security header - builder.addHeader(HTTP_SECURITY_CSP, HTTP_SECURITY_CSP_VALUE); - builder.addHeader(HTTP_SECURITY_RP, HTTP_SECURITY_RP_VALUE); - builder.addHeader(HTTP_SECURITY_XCTO, HTTP_SECURITY_XCTO_VALUE); - builder.addHeader(HTTP_SECURITY_XFO, HTTP_SECURITY_XFO_VALUE); - builder.addHeader(HTTP_SECURITY_XPCDP, HTTP_SECURITY_XPCDP_VALUE); - builder.addHeader(HTTP_SECURITY_XXP, HTTP_SECURITY_XXP_VALUE); + if (System.getProperty(HTTP_SECURITY_CSP) != null) { + builder.addHeader(HTTP_SECURITY_CSP, System.getProperty(HTTP_SECURITY_CSP)); + } + else { + builder.addHeader(HTTP_SECURITY_CSP, HTTP_SECURITY_CSP_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_RP) != null) { + builder.addHeader(HTTP_SECURITY_RP, System.getProperty(HTTP_SECURITY_RP)); + } + else { + builder.addHeader(HTTP_SECURITY_RP, HTTP_SECURITY_RP_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_XCTO) != null) { + builder.addHeader(HTTP_SECURITY_XCTO, System.getProperty(HTTP_SECURITY_XCTO)); + } + else { + builder.addHeader(HTTP_SECURITY_XCTO, HTTP_SECURITY_XCTO_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_XFO) != null) { + builder.addHeader(HTTP_SECURITY_XFO, System.getProperty(HTTP_SECURITY_XFO)); + } + else { + builder.addHeader(HTTP_SECURITY_XFO, HTTP_SECURITY_XFO_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_XPCDP) != null) { + builder.addHeader(HTTP_SECURITY_XPCDP, System.getProperty(HTTP_SECURITY_XPCDP)); + } + else { + builder.addHeader(HTTP_SECURITY_XPCDP, HTTP_SECURITY_XPCDP_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_XXP) != null) { + builder.addHeader(HTTP_SECURITY_XXP, System.getProperty(HTTP_SECURITY_XXP)); + } + else { + builder.addHeader(HTTP_SECURITY_XXP, HTTP_SECURITY_XXP_VALUE); + } return builder.url(url); } diff --git a/presto-main/src/main/java/io/prestosql/server/security/HttpSecurityHeaderFilter.java b/presto-main/src/main/java/io/prestosql/server/security/HttpSecurityHeaderFilter.java index deaacab07..80145934c 100644 --- a/presto-main/src/main/java/io/prestosql/server/security/HttpSecurityHeaderFilter.java +++ b/presto-main/src/main/java/io/prestosql/server/security/HttpSecurityHeaderFilter.java @@ -55,12 +55,47 @@ public class HttpSecurityHeaderFilter throws IOException, ServletException { HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse; - httpServletResponse.setHeader(HTTP_SECURITY_CSP, HTTP_SECURITY_CSP_VALUE); - httpServletResponse.setHeader(HTTP_SECURITY_RP, HTTP_SECURITY_RP_VALUE); - httpServletResponse.setHeader(HTTP_SECURITY_XCTO, HTTP_SECURITY_XCTO_VALUE); - httpServletResponse.setHeader(HTTP_SECURITY_XFO, HTTP_SECURITY_XFO_VALUE); - httpServletResponse.setHeader(HTTP_SECURITY_XPCDP, HTTP_SECURITY_XPCDP_VALUE); - httpServletResponse.setHeader(HTTP_SECURITY_XXP, HTTP_SECURITY_XXP_VALUE); + if (System.getProperty(HTTP_SECURITY_CSP) != null) { + httpServletResponse.setHeader(HTTP_SECURITY_CSP, System.getProperty(HTTP_SECURITY_CSP)); + } + else { + httpServletResponse.setHeader(HTTP_SECURITY_CSP, HTTP_SECURITY_CSP_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_RP) != null) { + httpServletResponse.setHeader(HTTP_SECURITY_RP, System.getProperty(HTTP_SECURITY_RP)); + } + else { + httpServletResponse.setHeader(HTTP_SECURITY_RP, HTTP_SECURITY_RP_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_XCTO) != null) { + httpServletResponse.setHeader(HTTP_SECURITY_XCTO, System.getProperty(HTTP_SECURITY_XCTO)); + } + else { + httpServletResponse.setHeader(HTTP_SECURITY_XCTO, HTTP_SECURITY_XCTO_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_XFO) != null) { + httpServletResponse.setHeader(HTTP_SECURITY_XFO, System.getProperty(HTTP_SECURITY_XFO)); + } + else { + httpServletResponse.setHeader(HTTP_SECURITY_XFO, HTTP_SECURITY_XFO_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_XPCDP) != null) { + httpServletResponse.setHeader(HTTP_SECURITY_XPCDP, System.getProperty(HTTP_SECURITY_XPCDP)); + } + else { + httpServletResponse.setHeader(HTTP_SECURITY_XPCDP, HTTP_SECURITY_XPCDP_VALUE); + } + + if (System.getProperty(HTTP_SECURITY_XXP) != null) { + httpServletResponse.setHeader(HTTP_SECURITY_XXP, System.getProperty(HTTP_SECURITY_XXP)); + } + else { + httpServletResponse.setHeader(HTTP_SECURITY_XXP, HTTP_SECURITY_XXP_VALUE); + } filterChain.doFilter(servletRequest, servletResponse); } } diff --git a/presto-main/src/main/java/io/prestosql/server/security/SecurityConfig.java b/presto-main/src/main/java/io/prestosql/server/security/SecurityConfig.java index fc31b5b85..30a4f2f88 100644 --- a/presto-main/src/main/java/io/prestosql/server/security/SecurityConfig.java +++ b/presto-main/src/main/java/io/prestosql/server/security/SecurityConfig.java @@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableList; import io.airlift.configuration.Config; import io.airlift.configuration.ConfigDescription; import io.airlift.configuration.DefunctConfig; +import io.prestosql.client.HttpSecurityHeadersConstants; import javax.validation.constraints.NotNull; @@ -41,6 +42,22 @@ public class SecurityConfig JWT } + private String httpHeaderCsp = HttpSecurityHeadersConstants.HTTP_SECURITY_CSP_VALUE; + private String httpHeaderRp = HttpSecurityHeadersConstants.HTTP_SECURITY_RP_VALUE; + private String httpHeaderXcto = HttpSecurityHeadersConstants.HTTP_SECURITY_XCTO_VALUE; + private String httpHeaderXfo = HttpSecurityHeadersConstants.HTTP_SECURITY_XFO_VALUE; + private String httpHeaderXpcdp = HttpSecurityHeadersConstants.HTTP_SECURITY_XPCDP_VALUE; + private String httpHeaderXxp = HttpSecurityHeadersConstants.HTTP_SECURITY_XXP_VALUE; + + { + System.setProperty(HttpSecurityHeadersConstants.HTTP_SECURITY_CSP, httpHeaderCsp); + System.setProperty(HttpSecurityHeadersConstants.HTTP_SECURITY_RP, httpHeaderRp); + System.setProperty(HttpSecurityHeadersConstants.HTTP_SECURITY_XCTO, httpHeaderXcto); + System.setProperty(HttpSecurityHeadersConstants.HTTP_SECURITY_XFO, httpHeaderXfo); + System.setProperty(HttpSecurityHeadersConstants.HTTP_SECURITY_XPCDP, httpHeaderXpcdp); + System.setProperty(HttpSecurityHeadersConstants.HTTP_SECURITY_XXP, httpHeaderXxp); + } + @NotNull public List getAuthenticationTypes() { @@ -67,4 +84,82 @@ public class SecurityConfig .collect(toImmutableList()); return this; } + + public String getHttpHeaderCsp() + { + return this.httpHeaderCsp; + } + + @Config("http-header.content-security-policy") + public SecurityConfig setHttpHeaderCsp(String httpHeaderCsp) + { + this.httpHeaderCsp = httpHeaderCsp; + System.setProperty(HttpSecurityHeadersConstants.HTTP_SECURITY_CSP, httpHeaderCsp); + return this; + } + + public String getHttpHeaderRp() + { + return httpHeaderRp; + } + + @Config("http-header.referrer-policy") + public SecurityConfig setHttpHeaderRp(String httpHeaderRp) + { + this.httpHeaderRp = httpHeaderRp; + System.setProperty(HttpSecurityHeadersConstants.HTTP_SECURITY_RP, httpHeaderRp); + return this; + } + + public String getHttpHeaderXcto() + { + return httpHeaderXcto; + } + + @Config("http-header.x-content-type-options") + public SecurityConfig setHttpHeaderXcto(String httpHeaderXcto) + { + this.httpHeaderXcto = httpHeaderXcto; + System.setProperty(HttpSecurityHeadersConstants.HTTP_SECURITY_XCTO, httpHeaderXcto); + return this; + } + + public String getHttpHeaderXfo() + { + return httpHeaderXfo; + } + + @Config("http-header.x-frame-options") + public SecurityConfig setHttpHeaderXfo(String httpHeaderXfo) + { + this.httpHeaderXfo = httpHeaderXfo; + System.setProperty(HttpSecurityHeadersConstants.HTTP_SECURITY_XFO, httpHeaderXfo); + return this; + } + + public String getHttpHeaderXpcdp() + { + return httpHeaderXpcdp; + } + + @Config("http-header.x-permitted-cross-domain-policies") + public SecurityConfig setHttpHeaderXpcdp(String httpHeaderXpcdp) + { + this.httpHeaderXpcdp = httpHeaderXpcdp; + System.setProperty(HttpSecurityHeadersConstants.HTTP_SECURITY_XPCDP, httpHeaderXpcdp); + return this; + } + + public String getHttpHeaderXxp() + { + return httpHeaderXxp; + } + + @Config("http-header.x-xss-protection") + public SecurityConfig setHttpHeaderXxp(String httpHeaderXxp) + { + this.httpHeaderXxp = httpHeaderXxp; + System.setProperty(HttpSecurityHeadersConstants.HTTP_SECURITY_XXP, httpHeaderXxp); + return this; + } } diff --git a/presto-main/src/test/java/io/prestosql/server/security/TestSecurityConfig.java b/presto-main/src/test/java/io/prestosql/server/security/TestSecurityConfig.java index cfd5e57ea..6b842eb05 100644 --- a/presto-main/src/test/java/io/prestosql/server/security/TestSecurityConfig.java +++ b/presto-main/src/test/java/io/prestosql/server/security/TestSecurityConfig.java @@ -29,7 +29,13 @@ public class TestSecurityConfig public void testDefaults() { ConfigAssertions.assertRecordedDefaults(ConfigAssertions.recordDefaults(SecurityConfig.class) - .setAuthenticationTypes("")); + .setAuthenticationTypes("") + .setHttpHeaderCsp("object-src 'none'") + .setHttpHeaderRp("strict-origin-when-cross-origin") + .setHttpHeaderXcto("nosniff") + .setHttpHeaderXfo("deny") + .setHttpHeaderXpcdp("master-only") + .setHttpHeaderXxp("1; mode=block")); } @Test @@ -37,10 +43,22 @@ public class TestSecurityConfig { Map properties = new ImmutableMap.Builder() .put("http-server.authentication.type", "KERBEROS,PASSWORD") + .put("http-header.content-security-policy", "script-src 'self'") + .put("http-header.referrer-policy", "origin") + .put("http-header.x-content-type-options", "none") + .put("http-header.x-frame-options", "none") + .put("http-header.x-permitted-cross-domain-policies", "sameorigin") + .put("http-header.x-xss-protection", "0") .build(); SecurityConfig expected = new SecurityConfig() - .setAuthenticationTypes(ImmutableList.of(KERBEROS, PASSWORD)); + .setAuthenticationTypes(ImmutableList.of(KERBEROS, PASSWORD)) + .setHttpHeaderCsp("script-src 'self'") + .setHttpHeaderRp("origin") + .setHttpHeaderXcto("none") + .setHttpHeaderXfo("none") + .setHttpHeaderXpcdp("sameorigin") + .setHttpHeaderXxp("0"); ConfigAssertions.assertFullMapping(properties, expected); }