The security headers middleware (added in internal/middleware/headers.go) currently uses 'unsafe-inline' for both script-src and style-src in the CSP. This is a pragmatic baseline but weakens the protection CSP provides against XSS.
Steps to remove 'unsafe-inline'
-
Add per-request nonce generation to tmpl.Renderer — generate a cryptographic random nonce for each request, make it available to templates via pageData, and inject nonce="..." on all <script> tags in base.html and room.html.
-
Migrate inline event handlers to external JS — three inline handlers need to move to addEventListener in external JS modules:
onclick in base.html
onclick in room-panel.html
onkeydown in room.html
-
Update CSP to use 'nonce-{value}' — replace 'unsafe-inline' with 'nonce-{value}' in script-src. The middleware will need access to the per-request nonce (e.g. via response header or context value).
-
Evaluate style-src — determine whether 'unsafe-inline' can also be dropped from style-src (check for inline style="" attributes and any dynamically set styles in JS).
Context
The current CSP still provides value by restricting connect-src, frame-src, object-src, base-uri, and form-action. Removing 'unsafe-inline' from script-src is the highest-impact improvement.
The security headers middleware (added in
internal/middleware/headers.go) currently uses'unsafe-inline'for bothscript-srcandstyle-srcin the CSP. This is a pragmatic baseline but weakens the protection CSP provides against XSS.Steps to remove
'unsafe-inline'Add per-request nonce generation to
tmpl.Renderer— generate a cryptographic random nonce for each request, make it available to templates viapageData, and injectnonce="..."on all<script>tags inbase.htmlandroom.html.Migrate inline event handlers to external JS — three inline handlers need to move to
addEventListenerin external JS modules:onclickinbase.htmlonclickinroom-panel.htmlonkeydowninroom.htmlUpdate CSP to use
'nonce-{value}'— replace'unsafe-inline'with'nonce-{value}'inscript-src. The middleware will need access to the per-request nonce (e.g. via response header or context value).Evaluate
style-src— determine whether'unsafe-inline'can also be dropped fromstyle-src(check for inlinestyle=""attributes and any dynamically set styles in JS).Context
The current CSP still provides value by restricting
connect-src,frame-src,object-src,base-uri, andform-action. Removing'unsafe-inline'fromscript-srcis the highest-impact improvement.