go,tmpl: unify handling of CSP
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
surtur 2023-09-08 17:48:51 +02:00
parent 73915fcd98
commit 1d159e4f64
Signed by: wanderer
SSH Key Fingerprint: SHA256:MdCZyJ2sHLltrLBp0xQO0O1qTW9BT/xl5nXkDvhlMCI
5 changed files with 45 additions and 14 deletions

@ -139,7 +139,13 @@ func (a *App) SetServerSettings() {
e.Use(session.Middleware(store)) e.Use(session.Middleware(store))
e.Use(middleware.Secure()) e.Use(
middleware.SecureWithConfig(
middleware.SecureConfig{
ContentSecurityPolicy: a.setting.HTTPCSP(),
},
),
)
if a.setting.HTTPGzipEnabled() { if a.setting.HTTPGzipEnabled() {
e.Use(middleware.GzipWithConfig(middleware.GzipConfig{ e.Use(middleware.GzipWithConfig(middleware.GzipConfig{

@ -50,6 +50,9 @@ func (s *Settings) sortOutFlags(conf *config.Config, hostFlag *string, portFlag
if d := *develFlag; d != conf.DevelMode { if d := *develFlag; d != conf.DevelMode {
log.Debugf(overrideMsg, "develMode", d) log.Debugf(overrideMsg, "develMode", d)
s.SetIsDevel(d) s.SetIsDevel(d)
log.Debug("making sure that CSP is set appropriately for devel mode (flag override)")
s.SetHTTPCSP(conf.HTTP.ContentSecurityPolicy)
} }
} }
} }

@ -22,6 +22,7 @@ type Settings struct {
httpGzipLevel int httpGzipLevel int
httpRateLimitEnabled bool httpRateLimitEnabled bool
httpRateLimit int httpRateLimit int
httpCSP string
isLive bool isLive bool
isDevel bool isDevel bool
initCreateAdmin bool initCreateAdmin bool
@ -49,6 +50,8 @@ const (
defaultPort = 3000 defaultPort = 3000
defaultSessionMaxAge = 86400 // seconds. defaultSessionMaxAge = 86400 // seconds.
defaultHTTPDomain = "localhost" defaultHTTPDomain = "localhost"
defaultCSP = "upgrade-insecure-requests; default-src 'self'; manifest-src 'self'; font-src 'self'; connect-src 'self'; script-src 'self'; style-src 'self'; object-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'"
defaultCSPDevel = "default-src 'self'; manifest-src 'self'; font-src 'self'; connect-src 'self' ws://localhost:3002 http://localhost:3002; script-src 'self' http://localhost:3002; style-src 'self'; object-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'"
defaultServerWriteTimeout = 30 * time.Second defaultServerWriteTimeout = 30 * time.Second
defaultServerReadHeaderTimeout = 30 * time.Second defaultServerReadHeaderTimeout = 30 * time.Second
defaultLoggerSkipAssets = true defaultLoggerSkipAssets = true
@ -138,6 +141,15 @@ func (s *Settings) Consolidate(conf *config.Config, host *string, port *int, dev
s.sessionEncrIsHex = true s.sessionEncrIsHex = true
} }
if conf.Init.CreateAdmin {
s.SetInitCreateAdmin(true)
s.SetInitAdminPassword(conf.Init.AdminPassword)
}
if conf.Registration.Allowed {
s.RegistrationAllowed = true
}
if conf.HTTP.Gzip > 0 { if conf.HTTP.Gzip > 0 {
s.SetHTTPGzipEnabled(true) s.SetHTTPGzipEnabled(true)
s.SetHTTPGzipLevel(conf.HTTP.Gzip) s.SetHTTPGzipLevel(conf.HTTP.Gzip)
@ -148,15 +160,7 @@ func (s *Settings) Consolidate(conf *config.Config, host *string, port *int, dev
s.SetHTTPRateLimit(conf.HTTP.RateLimit) s.SetHTTPRateLimit(conf.HTTP.RateLimit)
} }
if conf.Init.CreateAdmin { s.SetHTTPCSP(conf.HTTP.ContentSecurityPolicy)
s.SetInitCreateAdmin(true)
s.SetInitAdminPassword(conf.Init.AdminPassword)
}
if conf.Registration.Allowed {
s.RegistrationAllowed = true
}
s.SetHTTPDomain(conf.HTTP.Domain) s.SetHTTPDomain(conf.HTTP.Domain)
s.SetHTTPSecure(conf.HTTP.Secure) s.SetHTTPSecure(conf.HTTP.Secure)
s.setAPIKeys() s.setAPIKeys()
@ -269,6 +273,11 @@ func (s *Settings) HTTPRateLimit() int {
return s.httpRateLimit return s.httpRateLimit
} }
// HTTPCSP returns the httpCSP.
func (s *Settings) HTTPCSP() string {
return s.httpCSP
}
// AssetsPath returns the assetsPath. // AssetsPath returns the assetsPath.
func (s *Settings) AssetsPath() string { func (s *Settings) AssetsPath() string {
return s.assetsPath return s.assetsPath
@ -412,6 +421,20 @@ func (s *Settings) SetHTTPRateLimit(rateLimit int) {
s.httpRateLimit = rateLimit s.httpRateLimit = rateLimit
} }
// SetHTTPCSP sets the content security policy.
func (s *Settings) SetHTTPCSP(csp string) {
switch csp {
case "":
if s.isDevel {
s.httpCSP = defaultCSPDevel
} else {
s.httpCSP = defaultCSP
}
default:
s.httpCSP = csp
}
}
// SetAssetsPath sets the assetsPath. // SetAssetsPath sets the assetsPath.
func (s *Settings) SetAssetsPath(assetsPath string) { func (s *Settings) SetAssetsPath(assetsPath string) {
s.assetsPath = assetsPath s.assetsPath = assetsPath

@ -12,6 +12,7 @@ type page struct {
Title string Title string
Name string Name string
CSRF string CSRF string
CSP string
DevelMode bool DevelMode bool
Current string Current string
Error string Error string
@ -28,6 +29,7 @@ func newPage() *page {
p := &page{ p := &page{
AppName: appName, AppName: appName,
AppVer: appver, AppVer: appver,
CSP: setting.HTTPCSP(),
DevelMode: appIsDevel, DevelMode: appIsDevel,
Data: data, Data: data,
} }

@ -22,12 +22,9 @@
<link href="/assets/css/pcmt.css" rel="preload" as="style" integrity="{{- sha384 "css/pcmt.css" -}}"> <link href="/assets/css/pcmt.css" rel="preload" as="style" integrity="{{- sha384 "css/pcmt.css" -}}">
<link href="/assets/css/pcmt.css" rel="stylesheet" integrity="{{- sha384 "css/pcmt.css" -}}"> <link href="/assets/css/pcmt.css" rel="stylesheet" integrity="{{- sha384 "css/pcmt.css" -}}">
<meta http-equiv="content-security-policy" content="{{ .CSP }}"/>
{{- if .DevelMode -}} {{- if .DevelMode -}}
<!-- <meta http-equiv="content-security-policy" content="upgrade-insecure-requests; default-src 'self'; connect-src 'self' ws://localhost:3002 http://localhost:3002; script-src 'self' http://localhost:3002; style-src 'self' 'unsafe-inline';"/> -->
<meta http-equiv="content-security-policy" content="default-src 'self'; connect-src 'self' ws://localhost:3002 http://localhost:3002; script-src 'self' http://localhost:3002;"/>
<!-- inject browsersync script if running in devel mode --> <!-- inject browsersync script if running in devel mode -->
{{ template "browsersync.tmpl" }} {{ template "browsersync.tmpl" }}
{{ else }}
<meta http-equiv="content-security-policy" content="upgrade-insecure-requests; default-src 'self'; connect-src 'self'; script-src 'self';"/>
{{- end -}} {{- end -}}
</head> </head>