Headers middleware: support Content-Security-Policy-Report-Only
This commit is contained in:
parent
67f0700377
commit
b37aaea36d
17 changed files with 116 additions and 66 deletions
|
@ -394,6 +394,10 @@ This overrides the `BrowserXssFilter` option.
|
|||
|
||||
The `contentSecurityPolicy` option allows the `Content-Security-Policy` header value to be set with a custom value.
|
||||
|
||||
### `contentSecurityPolicyReportOnly`
|
||||
|
||||
The `contentSecurityPolicyReportOnly` option allows the `Content-Security-Policy-Report-Only` header value to be set with a custom value.
|
||||
|
||||
### `publicKey`
|
||||
|
||||
The `publicKey` implements HPKP to prevent MITM attacks with forged certificates.
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
- "traefik.http.middlewares.middleware12.headers.allowedhosts=foobar, foobar"
|
||||
- "traefik.http.middlewares.middleware12.headers.browserxssfilter=true"
|
||||
- "traefik.http.middlewares.middleware12.headers.contentsecuritypolicy=foobar"
|
||||
- "traefik.http.middlewares.middleware12.headers.contentsecuritypolicyreportonly=foobar"
|
||||
- "traefik.http.middlewares.middleware12.headers.contenttypenosniff=true"
|
||||
- "traefik.http.middlewares.middleware12.headers.custombrowserxssvalue=foobar"
|
||||
- "traefik.http.middlewares.middleware12.headers.customframeoptionsvalue=foobar"
|
||||
|
|
|
@ -198,6 +198,7 @@
|
|||
browserXssFilter = true
|
||||
customBrowserXSSValue = "foobar"
|
||||
contentSecurityPolicy = "foobar"
|
||||
contentSecurityPolicyReportOnly = "foobar"
|
||||
publicKey = "foobar"
|
||||
referrerPolicy = "foobar"
|
||||
permissionsPolicy = "foobar"
|
||||
|
|
|
@ -242,6 +242,7 @@ http:
|
|||
browserXssFilter: true
|
||||
customBrowserXSSValue: foobar
|
||||
contentSecurityPolicy: foobar
|
||||
contentSecurityPolicyReportOnly: foobar
|
||||
publicKey: foobar
|
||||
referrerPolicy: foobar
|
||||
permissionsPolicy: foobar
|
||||
|
|
|
@ -1309,6 +1309,10 @@ spec:
|
|||
description: ContentSecurityPolicy defines the Content-Security-Policy
|
||||
header value.
|
||||
type: string
|
||||
contentSecurityPolicyReportOnly:
|
||||
description: ContentSecurityPolicyReportOnly defines the Content-Security-Policy-Report-Only
|
||||
header value.
|
||||
type: string
|
||||
contentTypeNosniff:
|
||||
description: ContentTypeNosniff defines whether to add the X-Content-Type-Options
|
||||
header with the nosniff value.
|
||||
|
|
|
@ -71,6 +71,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
|
|||
| `traefik/http/middlewares/Middleware12/headers/allowedHosts/1` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware12/headers/browserXssFilter` | `true` |
|
||||
| `traefik/http/middlewares/Middleware12/headers/contentSecurityPolicy` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware12/headers/contentSecurityPolicyReportOnly` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware12/headers/contentTypeNosniff` | `true` |
|
||||
| `traefik/http/middlewares/Middleware12/headers/customBrowserXSSValue` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware12/headers/customFrameOptionsValue` | `foobar` |
|
||||
|
|
|
@ -585,6 +585,10 @@ spec:
|
|||
description: ContentSecurityPolicy defines the Content-Security-Policy
|
||||
header value.
|
||||
type: string
|
||||
contentSecurityPolicyReportOnly:
|
||||
description: ContentSecurityPolicyReportOnly defines the Content-Security-Policy-Report-Only
|
||||
header value.
|
||||
type: string
|
||||
contentTypeNosniff:
|
||||
description: ContentTypeNosniff defines whether to add the X-Content-Type-Options
|
||||
header with the nosniff value.
|
||||
|
|
|
@ -1309,6 +1309,10 @@ spec:
|
|||
description: ContentSecurityPolicy defines the Content-Security-Policy
|
||||
header value.
|
||||
type: string
|
||||
contentSecurityPolicyReportOnly:
|
||||
description: ContentSecurityPolicyReportOnly defines the Content-Security-Policy-Report-Only
|
||||
header value.
|
||||
type: string
|
||||
contentTypeNosniff:
|
||||
description: ContentTypeNosniff defines whether to add the X-Content-Type-Options
|
||||
header with the nosniff value.
|
||||
|
|
|
@ -330,6 +330,7 @@
|
|||
browserXssFilter = true
|
||||
customBrowserXSSValue = "foobar"
|
||||
contentSecurityPolicy = "foobar"
|
||||
contentSecurityPolicyReportOnly = "foobar"
|
||||
publicKey = "foobar"
|
||||
referrerPolicy = "foobar"
|
||||
isDevelopment = true
|
||||
|
|
|
@ -313,6 +313,8 @@ type Headers struct {
|
|||
CustomBrowserXSSValue string `json:"customBrowserXSSValue,omitempty" toml:"customBrowserXSSValue,omitempty" yaml:"customBrowserXSSValue,omitempty"`
|
||||
// ContentSecurityPolicy defines the Content-Security-Policy header value.
|
||||
ContentSecurityPolicy string `json:"contentSecurityPolicy,omitempty" toml:"contentSecurityPolicy,omitempty" yaml:"contentSecurityPolicy,omitempty"`
|
||||
// ContentSecurityPolicyReportOnly defines the Content-Security-Policy-Report-Only header value.
|
||||
ContentSecurityPolicyReportOnly string `json:"contentSecurityPolicyReportOnly,omitempty" toml:"contentSecurityPolicyReportOnly,omitempty" yaml:"contentSecurityPolicyReportOnly,omitempty"`
|
||||
// PublicKey is the public key that implements HPKP to prevent MITM attacks with forged certificates.
|
||||
PublicKey string `json:"publicKey,omitempty" toml:"publicKey,omitempty" yaml:"publicKey,omitempty"`
|
||||
// ReferrerPolicy defines the Referrer-Policy header value.
|
||||
|
@ -376,6 +378,7 @@ func (h *Headers) HasSecureHeadersDefined() bool {
|
|||
h.BrowserXSSFilter ||
|
||||
h.CustomBrowserXSSValue != "" ||
|
||||
h.ContentSecurityPolicy != "" ||
|
||||
h.ContentSecurityPolicyReportOnly != "" ||
|
||||
h.PublicKey != "" ||
|
||||
h.ReferrerPolicy != "" ||
|
||||
(h.FeaturePolicy != nil && *h.FeaturePolicy != "") ||
|
||||
|
|
|
@ -63,6 +63,7 @@ func TestDecodeConfiguration(t *testing.T) {
|
|||
"traefik.http.middlewares.Middleware8.headers.addvaryheader": "true",
|
||||
"traefik.http.middlewares.Middleware8.headers.browserxssfilter": "true",
|
||||
"traefik.http.middlewares.Middleware8.headers.contentsecuritypolicy": "foobar",
|
||||
"traefik.http.middlewares.Middleware8.headers.contentsecuritypolicyreportonly": "foobar",
|
||||
"traefik.http.middlewares.Middleware8.headers.contenttypenosniff": "true",
|
||||
"traefik.http.middlewares.Middleware8.headers.custombrowserxssvalue": "foobar",
|
||||
"traefik.http.middlewares.Middleware8.headers.customframeoptionsvalue": "foobar",
|
||||
|
@ -611,22 +612,23 @@ func TestDecodeConfiguration(t *testing.T) {
|
|||
"name0": "foobar",
|
||||
"name1": "foobar",
|
||||
},
|
||||
SSLForceHost: Bool(true),
|
||||
STSSeconds: 42,
|
||||
STSIncludeSubdomains: true,
|
||||
STSPreload: true,
|
||||
ForceSTSHeader: true,
|
||||
FrameDeny: true,
|
||||
CustomFrameOptionsValue: "foobar",
|
||||
ContentTypeNosniff: true,
|
||||
BrowserXSSFilter: true,
|
||||
CustomBrowserXSSValue: "foobar",
|
||||
ContentSecurityPolicy: "foobar",
|
||||
PublicKey: "foobar",
|
||||
ReferrerPolicy: "foobar",
|
||||
FeaturePolicy: String("foobar"),
|
||||
PermissionsPolicy: "foobar",
|
||||
IsDevelopment: true,
|
||||
SSLForceHost: Bool(true),
|
||||
STSSeconds: 42,
|
||||
STSIncludeSubdomains: true,
|
||||
STSPreload: true,
|
||||
ForceSTSHeader: true,
|
||||
FrameDeny: true,
|
||||
CustomFrameOptionsValue: "foobar",
|
||||
ContentTypeNosniff: true,
|
||||
BrowserXSSFilter: true,
|
||||
CustomBrowserXSSValue: "foobar",
|
||||
ContentSecurityPolicy: "foobar",
|
||||
ContentSecurityPolicyReportOnly: "foobar",
|
||||
PublicKey: "foobar",
|
||||
ReferrerPolicy: "foobar",
|
||||
FeaturePolicy: String("foobar"),
|
||||
PermissionsPolicy: "foobar",
|
||||
IsDevelopment: true,
|
||||
},
|
||||
},
|
||||
"Middleware9": {
|
||||
|
@ -1134,22 +1136,23 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
"name0": "foobar",
|
||||
"name1": "foobar",
|
||||
},
|
||||
SSLForceHost: Bool(true),
|
||||
STSSeconds: 42,
|
||||
STSIncludeSubdomains: true,
|
||||
STSPreload: true,
|
||||
ForceSTSHeader: true,
|
||||
FrameDeny: true,
|
||||
CustomFrameOptionsValue: "foobar",
|
||||
ContentTypeNosniff: true,
|
||||
BrowserXSSFilter: true,
|
||||
CustomBrowserXSSValue: "foobar",
|
||||
ContentSecurityPolicy: "foobar",
|
||||
PublicKey: "foobar",
|
||||
ReferrerPolicy: "foobar",
|
||||
FeaturePolicy: String("foobar"),
|
||||
PermissionsPolicy: "foobar",
|
||||
IsDevelopment: true,
|
||||
SSLForceHost: Bool(true),
|
||||
STSSeconds: 42,
|
||||
STSIncludeSubdomains: true,
|
||||
STSPreload: true,
|
||||
ForceSTSHeader: true,
|
||||
FrameDeny: true,
|
||||
CustomFrameOptionsValue: "foobar",
|
||||
ContentTypeNosniff: true,
|
||||
BrowserXSSFilter: true,
|
||||
CustomBrowserXSSValue: "foobar",
|
||||
ContentSecurityPolicy: "foobar",
|
||||
ContentSecurityPolicyReportOnly: "foobar",
|
||||
PublicKey: "foobar",
|
||||
ReferrerPolicy: "foobar",
|
||||
FeaturePolicy: String("foobar"),
|
||||
PermissionsPolicy: "foobar",
|
||||
IsDevelopment: true,
|
||||
},
|
||||
},
|
||||
"Middleware9": {
|
||||
|
@ -1299,6 +1302,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
"traefik.HTTP.Middlewares.Middleware8.Headers.AllowedHosts": "foobar, fiibar",
|
||||
"traefik.HTTP.Middlewares.Middleware8.Headers.BrowserXSSFilter": "true",
|
||||
"traefik.HTTP.Middlewares.Middleware8.Headers.ContentSecurityPolicy": "foobar",
|
||||
"traefik.HTTP.Middlewares.Middleware8.Headers.ContentSecurityPolicyReportOnly": "foobar",
|
||||
"traefik.HTTP.Middlewares.Middleware8.Headers.ContentTypeNosniff": "true",
|
||||
"traefik.HTTP.Middlewares.Middleware8.Headers.CustomBrowserXSSValue": "foobar",
|
||||
"traefik.HTTP.Middlewares.Middleware8.Headers.CustomFrameOptionsValue": "foobar",
|
||||
|
|
|
@ -17,24 +17,25 @@ type secureHeader struct {
|
|||
// newSecure constructs a new secure instance with supplied options.
|
||||
func newSecure(next http.Handler, cfg dynamic.Headers, contextKey string) *secureHeader {
|
||||
opt := secure.Options{
|
||||
BrowserXssFilter: cfg.BrowserXSSFilter,
|
||||
ContentTypeNosniff: cfg.ContentTypeNosniff,
|
||||
ForceSTSHeader: cfg.ForceSTSHeader,
|
||||
FrameDeny: cfg.FrameDeny,
|
||||
IsDevelopment: cfg.IsDevelopment,
|
||||
STSIncludeSubdomains: cfg.STSIncludeSubdomains,
|
||||
STSPreload: cfg.STSPreload,
|
||||
ContentSecurityPolicy: cfg.ContentSecurityPolicy,
|
||||
CustomBrowserXssValue: cfg.CustomBrowserXSSValue,
|
||||
CustomFrameOptionsValue: cfg.CustomFrameOptionsValue,
|
||||
PublicKey: cfg.PublicKey,
|
||||
ReferrerPolicy: cfg.ReferrerPolicy,
|
||||
AllowedHosts: cfg.AllowedHosts,
|
||||
HostsProxyHeaders: cfg.HostsProxyHeaders,
|
||||
SSLProxyHeaders: cfg.SSLProxyHeaders,
|
||||
STSSeconds: cfg.STSSeconds,
|
||||
PermissionsPolicy: cfg.PermissionsPolicy,
|
||||
SecureContextKey: contextKey,
|
||||
BrowserXssFilter: cfg.BrowserXSSFilter,
|
||||
ContentTypeNosniff: cfg.ContentTypeNosniff,
|
||||
ForceSTSHeader: cfg.ForceSTSHeader,
|
||||
FrameDeny: cfg.FrameDeny,
|
||||
IsDevelopment: cfg.IsDevelopment,
|
||||
STSIncludeSubdomains: cfg.STSIncludeSubdomains,
|
||||
STSPreload: cfg.STSPreload,
|
||||
ContentSecurityPolicy: cfg.ContentSecurityPolicy,
|
||||
ContentSecurityPolicyReportOnly: cfg.ContentSecurityPolicyReportOnly,
|
||||
CustomBrowserXssValue: cfg.CustomBrowserXSSValue,
|
||||
CustomFrameOptionsValue: cfg.CustomFrameOptionsValue,
|
||||
PublicKey: cfg.PublicKey,
|
||||
ReferrerPolicy: cfg.ReferrerPolicy,
|
||||
AllowedHosts: cfg.AllowedHosts,
|
||||
HostsProxyHeaders: cfg.HostsProxyHeaders,
|
||||
SSLProxyHeaders: cfg.SSLProxyHeaders,
|
||||
STSSeconds: cfg.STSSeconds,
|
||||
PermissionsPolicy: cfg.PermissionsPolicy,
|
||||
SecureContextKey: contextKey,
|
||||
}
|
||||
|
||||
return &secureHeader{
|
||||
|
|
|
@ -139,6 +139,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
"traefik/http/middlewares/Middleware09/headers/accessControlExposeHeaders/0": "foobar",
|
||||
"traefik/http/middlewares/Middleware09/headers/accessControlExposeHeaders/1": "foobar",
|
||||
"traefik/http/middlewares/Middleware09/headers/contentSecurityPolicy": "foobar",
|
||||
"traefik/http/middlewares/Middleware09/headers/contentSecurityPolicyReportOnly": "foobar",
|
||||
"traefik/http/middlewares/Middleware09/headers/publicKey": "foobar",
|
||||
"traefik/http/middlewares/Middleware09/headers/customRequestHeaders/name0": "foobar",
|
||||
"traefik/http/middlewares/Middleware09/headers/customRequestHeaders/name1": "foobar",
|
||||
|
@ -601,22 +602,23 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
"name1": "foobar",
|
||||
"name0": "foobar",
|
||||
},
|
||||
SSLForceHost: Bool(true),
|
||||
STSSeconds: 42,
|
||||
STSIncludeSubdomains: true,
|
||||
STSPreload: true,
|
||||
ForceSTSHeader: true,
|
||||
FrameDeny: true,
|
||||
CustomFrameOptionsValue: "foobar",
|
||||
ContentTypeNosniff: true,
|
||||
BrowserXSSFilter: true,
|
||||
CustomBrowserXSSValue: "foobar",
|
||||
ContentSecurityPolicy: "foobar",
|
||||
PublicKey: "foobar",
|
||||
ReferrerPolicy: "foobar",
|
||||
FeaturePolicy: String("foobar"),
|
||||
PermissionsPolicy: "foobar",
|
||||
IsDevelopment: true,
|
||||
SSLForceHost: Bool(true),
|
||||
STSSeconds: 42,
|
||||
STSIncludeSubdomains: true,
|
||||
STSPreload: true,
|
||||
ForceSTSHeader: true,
|
||||
FrameDeny: true,
|
||||
CustomFrameOptionsValue: "foobar",
|
||||
ContentTypeNosniff: true,
|
||||
BrowserXSSFilter: true,
|
||||
CustomBrowserXSSValue: "foobar",
|
||||
ContentSecurityPolicy: "foobar",
|
||||
ContentSecurityPolicyReportOnly: "foobar",
|
||||
PublicKey: "foobar",
|
||||
ReferrerPolicy: "foobar",
|
||||
FeaturePolicy: String("foobar"),
|
||||
PermissionsPolicy: "foobar",
|
||||
IsDevelopment: true,
|
||||
},
|
||||
},
|
||||
"Middleware17": {
|
||||
|
|
|
@ -214,6 +214,7 @@ func init() {
|
|||
BrowserXSSFilter: true,
|
||||
CustomBrowserXSSValue: "foo",
|
||||
ContentSecurityPolicy: "foo",
|
||||
ContentSecurityPolicyReportOnly: "foo",
|
||||
PublicKey: "foo",
|
||||
ReferrerPolicy: "foo",
|
||||
PermissionsPolicy: "foo",
|
||||
|
|
|
@ -170,6 +170,7 @@
|
|||
"browserXssFilter": true,
|
||||
"customBrowserXSSValue": "xxxx",
|
||||
"contentSecurityPolicy": "xxxx",
|
||||
"contentSecurityPolicyReportOnly": "xxxx",
|
||||
"publicKey": "xxxx",
|
||||
"referrerPolicy": "foo",
|
||||
"permissionsPolicy": "foo",
|
||||
|
|
|
@ -173,6 +173,7 @@
|
|||
"browserXssFilter": true,
|
||||
"customBrowserXSSValue": "foo",
|
||||
"contentSecurityPolicy": "foo",
|
||||
"contentSecurityPolicyReportOnly": "foo",
|
||||
"publicKey": "foo",
|
||||
"referrerPolicy": "foo",
|
||||
"permissionsPolicy": "foo",
|
||||
|
|
|
@ -817,6 +817,22 @@
|
|||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<!-- EXTRA FIELDS FROM MIDDLEWARES - [headers] - contentSecurityPolicyReportOnly -->
|
||||
<q-card-section v-if="middleware.headers">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">
|
||||
Content Security Policy (Report Only)
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-green"
|
||||
>
|
||||
{{ exData(middleware).contentSecurityPolicyReportOnly }}
|
||||
</q-chip>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<!-- EXTRA FIELDS FROM MIDDLEWARES - [headers] - publicKey -->
|
||||
<q-card-section v-if="middleware.headers">
|
||||
<div class="row items-start no-wrap">
|
||||
|
|
Loading…
Reference in a new issue