feat(server): csp template (#2856)
Implements the ability for advanced users to override the CSP and easily include the required nonce.pull/2891/head
parent
6043b43d94
commit
bed7a8ae32
|
@ -71,6 +71,12 @@ server:
|
|||
## The path to the DER base64/PEM format public certificate.
|
||||
certificate: ""
|
||||
|
||||
## Server headers configuration/customization.
|
||||
headers:
|
||||
|
||||
## The CSP Template. Read the docs.
|
||||
csp_template: ""
|
||||
|
||||
##
|
||||
## Log Configuration
|
||||
##
|
||||
|
|
|
@ -24,6 +24,8 @@ server:
|
|||
tls:
|
||||
key: ""
|
||||
certificate: ""
|
||||
headers:
|
||||
csp_template: ""
|
||||
```
|
||||
|
||||
## Options
|
||||
|
@ -209,6 +211,25 @@ required: situational
|
|||
|
||||
The path to the public certificate for TLS connections. Must be in DER base64/PEM format.
|
||||
|
||||
|
||||
### headers
|
||||
|
||||
#### csp_template
|
||||
<div markdown="1">
|
||||
type: string
|
||||
{: .label .label-config .label-purple }
|
||||
default: ""
|
||||
{: .label .label-config .label-blue }
|
||||
required: no
|
||||
{: .label .label-config .label-green }
|
||||
</div>
|
||||
|
||||
This customizes the value of the Content-Security-Policy header. It will replace all instances of `${NONCE}` with the
|
||||
nonce value of the Authelia react bundle. This is an advanced option to customize and you should do sufficient research
|
||||
about how browsers utilize and understand this header before attempting to customize it.
|
||||
|
||||
For example, the default CSP template is `default-src 'self'; object-src 'none'; style-src 'self' 'nonce-${NONCE}'`.
|
||||
|
||||
## Additional Notes
|
||||
|
||||
### Buffer Sizes
|
||||
|
|
|
@ -71,6 +71,12 @@ server:
|
|||
## The path to the DER base64/PEM format public certificate.
|
||||
certificate: ""
|
||||
|
||||
## Server headers configuration/customization.
|
||||
headers:
|
||||
|
||||
## The CSP Template. Read the docs.
|
||||
csp_template: ""
|
||||
|
||||
##
|
||||
## Log Configuration
|
||||
##
|
||||
|
|
|
@ -12,7 +12,8 @@ type ServerConfiguration struct {
|
|||
EnableExpvars bool `koanf:"enable_endpoint_expvars"`
|
||||
DisableHealthcheck bool `koanf:"disable_healthcheck"`
|
||||
|
||||
TLS ServerTLSConfiguration `koanf:"tls"`
|
||||
TLS ServerTLSConfiguration `koanf:"tls"`
|
||||
Headers ServerHeadersConfiguration `koanf:"headers"`
|
||||
}
|
||||
|
||||
// ServerTLSConfiguration represents the configuration of the http servers TLS options.
|
||||
|
@ -21,6 +22,11 @@ type ServerTLSConfiguration struct {
|
|||
Key string `koanf:"key"`
|
||||
}
|
||||
|
||||
// ServerHeadersConfiguration represents the customization of the http server headers.
|
||||
type ServerHeadersConfiguration struct {
|
||||
CSPTemplate string `koanf:"csp_template"`
|
||||
}
|
||||
|
||||
// DefaultServerConfiguration represents the default values of the ServerConfiguration.
|
||||
var DefaultServerConfiguration = ServerConfiguration{
|
||||
Host: "0.0.0.0",
|
||||
|
|
|
@ -171,6 +171,7 @@ var ValidKeys = []string{
|
|||
"server.disable_healthcheck",
|
||||
"server.tls.key",
|
||||
"server.tls.certificate",
|
||||
"server.headers.csp_template",
|
||||
|
||||
// TOTP Keys.
|
||||
"totp.issuer",
|
||||
|
|
|
@ -23,3 +23,9 @@ X_AUTHELIA_HEALTHCHECK_HOST=%s
|
|||
X_AUTHELIA_HEALTHCHECK_PORT=%d
|
||||
X_AUTHELIA_HEALTHCHECK_PATH=%s
|
||||
`
|
||||
|
||||
const (
|
||||
cspDefaultTemplate = "default-src 'self'; object-src 'none'; style-src 'self' 'nonce-%s'"
|
||||
cspDefaultDevTemplate = "default-src 'self' 'unsafe-eval'; object-src 'none'; style-src 'self' 'nonce-%s'"
|
||||
cspNoncePlaceholder = "${NONCE}"
|
||||
)
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/authelia/authelia/v4/internal/logging"
|
||||
|
@ -71,11 +72,13 @@ func ServeTemplatedFile(publicDir, file, assetPath, duoSelfEnrollment, rememberM
|
|||
|
||||
switch {
|
||||
case publicDir == swaggerAssets:
|
||||
ctx.Response.Header.Add("Content-Security-Policy", fmt.Sprintf("base-uri 'self' ; default-src 'self' ; img-src 'self' https://validator.swagger.io data: ; object-src 'none' ; script-src 'self' 'unsafe-inline' 'nonce-%s' ; style-src 'self' 'nonce-%s'", nonce, nonce))
|
||||
ctx.Response.Header.Add("Content-Security-Policy", fmt.Sprintf("base-uri 'self'; default-src 'self'; img-src 'self' https://validator.swagger.io data:; object-src 'none'; script-src 'self' 'unsafe-inline' 'nonce-%s'; style-src 'self' 'nonce-%s'", nonce, nonce))
|
||||
case ctx.Configuration.Server.Headers.CSPTemplate != "":
|
||||
ctx.Response.Header.Add("Content-Security-Policy", strings.ReplaceAll(ctx.Configuration.Server.Headers.CSPTemplate, cspNoncePlaceholder, nonce))
|
||||
case os.Getenv("ENVIRONMENT") == dev:
|
||||
ctx.Response.Header.Add("Content-Security-Policy", fmt.Sprintf("default-src 'self' 'unsafe-eval'; object-src 'none'; style-src 'self' 'nonce-%s'", nonce))
|
||||
ctx.Response.Header.Add("Content-Security-Policy", fmt.Sprintf(cspDefaultDevTemplate, nonce))
|
||||
default:
|
||||
ctx.Response.Header.Add("Content-Security-Policy", fmt.Sprintf("default-src 'self' ; object-src 'none'; style-src 'self' 'nonce-%s'", nonce))
|
||||
ctx.Response.Header.Add("Content-Security-Policy", fmt.Sprintf(cspDefaultTemplate, nonce))
|
||||
}
|
||||
|
||||
err := tmpl.Execute(ctx.Response.BodyWriter(), struct{ Base, BaseURL, CSPNonce, DuoSelfEnrollment, LogoOverride, RememberMe, ResetPassword, Session, Theme string }{Base: base, BaseURL: baseURL, CSPNonce: nonce, DuoSelfEnrollment: duoSelfEnrollment, LogoOverride: logoOverride, RememberMe: rememberMe, ResetPassword: resetPassword, Session: session, Theme: theme})
|
||||
|
|
Loading…
Reference in New Issue