From 7a74ff3e746ec531316d8b65c4f5e348800055ba Mon Sep 17 00:00:00 2001 From: fen Date: Thu, 10 Sep 2026 09:08:17 -0500 Subject: [PATCH] Fix #139: drop unsafe-inline from script-src and style-src (#139) - Move all inline `) + srcOnly := regexp.MustCompile(`]+src=`) + for _, e := range entries { + b, err := fs.ReadFile(tmplFS, "templates/"+e.Name()) + if err != nil { + t.Fatal(err) + } + for _, m := range re.FindAll(b, -1) { + if srcOnly.Match(m) { + continue // external script tag with src: fine + } + t.Errorf("%s: inline + {{template "foot" .}} diff --git a/internal/web/templates/can.html b/internal/web/templates/can.html index 2c21ae4..99ec9f3 100644 --- a/internal/web/templates/can.html +++ b/internal/web/templates/can.html @@ -1,7 +1,7 @@ {{template "head" .}} {{template "topbar" .}}
-
+

{{.Title}} can

{{if .HasDescription}}

{{.Description}}

{{end}} diff --git a/internal/web/templates/foot.html b/internal/web/templates/foot.html index 850e1fc..522a337 100644 --- a/internal/web/templates/foot.html +++ b/internal/web/templates/foot.html @@ -1,21 +1 @@ -{{define "foot"}}{{end}} \ No newline at end of file +{{define "foot"}}{{end}} \ No newline at end of file diff --git a/internal/web/templates/history.html b/internal/web/templates/history.html index fcb667f..cb6da95 100644 --- a/internal/web/templates/history.html +++ b/internal/web/templates/history.html @@ -8,7 +8,7 @@
- + @@ -20,7 +20,7 @@
Paste Language
- +
@@ -28,25 +28,5 @@
- + {{template "foot" .}} diff --git a/internal/web/templates/layout.html b/internal/web/templates/layout.html index ae1162b..ca8cbfc 100644 --- a/internal/web/templates/layout.html +++ b/internal/web/templates/layout.html @@ -2,82 +2,7 @@ - + {{end}} {{define "topbar"}} @@ -98,49 +23,5 @@
- + {{end}} diff --git a/internal/web/templates/mine.html b/internal/web/templates/mine.html index 2d7ec02..31bfdc4 100644 --- a/internal/web/templates/mine.html +++ b/internal/web/templates/mine.html @@ -8,7 +8,7 @@
- + @@ -19,7 +19,7 @@
Paste Language
- +
@@ -27,51 +27,5 @@
- + {{template "foot" .}} diff --git a/internal/web/templates/new.html b/internal/web/templates/new.html index b51e191..c2a7b4c 100644 --- a/internal/web/templates/new.html +++ b/internal/web/templates/new.html @@ -30,7 +30,7 @@
Ctrl+Enter to create -
+
@@ -46,8 +46,8 @@ -

Protection

- + - +
@@ -75,414 +75,17 @@
- +

Custom URL

- - + {{template "foot" .}} diff --git a/internal/web/templates/paste.html b/internal/web/templates/paste.html index ba9bae7..6040efb 100644 --- a/internal/web/templates/paste.html +++ b/internal/web/templates/paste.html @@ -8,13 +8,13 @@
raw - copy - {{if .DeletionToken}}delete{{end}} + copy + {{if .DeletionToken}}delete{{end}}
- @@ -35,7 +35,7 @@
{{if .JustCreated}}
-
+
Paste created. Link copied to clipboard: {{.Host}}/{{.ID}} {{if .DeletionToken}} · deletion token: {{.DeletionToken}}{{end}}
@@ -59,43 +59,5 @@
- + {{template "foot" .}} diff --git a/internal/web/templates/settings.html b/internal/web/templates/settings.html index 1720424..dff3571 100644 --- a/internal/web/templates/settings.html +++ b/internal/web/templates/settings.html @@ -13,102 +13,11 @@

Theme

-

Editor

- +

Editor

+
- + {{template "foot" .}} diff --git a/internal/web/templates/unlock.html b/internal/web/templates/unlock.html index 24182ce..f869088 100644 --- a/internal/web/templates/unlock.html +++ b/internal/web/templates/unlock.html @@ -18,12 +18,5 @@
Created {{.CreatedAgo}}
- + {{template "foot" .}} diff --git a/internal/web/web.go b/internal/web/web.go index b3a8166..074d183 100644 --- a/internal/web/web.go +++ b/internal/web/web.go @@ -383,8 +383,12 @@ func (u *UI) Handlers() *Handlers { return &Handlers{UI: u} } // #59: security headers for rendered HTML pages. Applied wherever the // response is text/html (page templates and the inline can page); JSON API -// responses and /raw content pass through untouched. script-src allows -// 'unsafe-inline' because the page templates carry inline scripts; CSP +// responses and /raw content pass through untouched. +// #139: script-src and style-src no longer allow 'unsafe-inline'. All +// previously-inline scripts moved to external files under static/ (page data +// reaches them via data-* attributes on the script tags), inline style +// attributes became CSS classes, and JS sets swatch colors via CSSOM. The +// img-src data: allowance stays: SVG data-URI backgrounds in app.css need it. // default-src 'self' still blocks external content and object/frame embeds, // and frame-ancestors 'none' closes the clickjacking gap flagged in the #34 // pentest. Runs after the handler so the Content-Type is already set. @@ -396,7 +400,7 @@ func SecurityHeaders(next http.Handler) http.Handler { // is harmless and arguably desirable. h := w.Header() h.Set("Content-Security-Policy", - "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none'") + "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; frame-ancestors 'none'") h.Set("Referrer-Policy", "no-referrer") h.Set("X-Content-Type-Options", "nosniff") next.ServeHTTP(w, r)