Skip to content

feat(viewer): add defense-in-depth security headers - #735

Merged
lizhengfeng101 merged 2 commits into
mainfrom
feat/viewer-security-headers
Aug 5, 2026
Merged

feat(viewer): add defense-in-depth security headers#735
lizhengfeng101 merged 2 commits into
mainfrom
feat/viewer-security-headers

Conversation

@lizhengfeng101

Copy link
Copy Markdown
Collaborator

What

Adds a security-headers middleware to the local web viewer, setting the following on every response:

  • Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'none'
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • Referrer-Policy: no-referrer
  • Permissions-Policy: geolocation=(), camera=(), microphone=()

To keep the CSP strict (no unsafe-inline), the previously-inline <script> in session.html — which uses no template variables — is externalized to static/session.js and served as a first-party asset.

Why

The viewer exposes session JSONL that contains reviewed source code and the LLM's analysis of it. These headers add defense-in-depth against content injection and clickjacking on the viewer's browser-facing surface, complementing the existing DNS-rebinding host-header allowlist.

HSTS is intentionally omitted: the viewer serves plain HTTP on loopback, where HSTS is meaningless and would wrongly pin localhost.

Changes

  • internal/viewer/securityheaders.go — new middleware, wrapped outermost in StartServer
  • internal/viewer/static/session.js — externalized session script
  • internal/viewer/templates/session.html — reference external script
  • internal/viewer/server.go — embed session.js, wire up middleware
  • internal/viewer/securityheaders_test.go — header presence, HSTS omission, CSP strictness
  • ASSURANCE_CASE.md — new CWE-79 (XSS) countermeasure row

Testing

  • gofmt -s -l clean
  • go build ./... passes
  • go test ./internal/viewer/ passes

Wrap the local viewer with a middleware that sets a strict
Content-Security-Policy (default-src 'self', no unsafe-inline) plus
X-Content-Type-Options, X-Frame-Options, Referrer-Policy, and
Permissions-Policy on every response. HSTS is intentionally omitted
since the viewer serves plain HTTP on loopback.

To keep the CSP strict without an 'unsafe-inline' relaxation, the
formerly-inline session script is externalized to static/session.js
(it uses no template variables). Update the assurance case with a
CWE-79 countermeasure row documenting these headers.

Adds tests covering header presence, HSTS omission, and CSP strictness.
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🔍 OpenCodeReview found 1 issue(s) in this PR.

  • ✅ Successfully posted inline: 1 comment(s)

Comment thread internal/viewer/static/session.js Outdated
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

@MuoDoo MuoDoo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@lizhengfeng101
lizhengfeng101 merged commit d1008b8 into main Aug 5, 2026
11 checks passed
@lizhengfeng101
lizhengfeng101 deleted the feat/viewer-security-headers branch August 5, 2026 09:42

@moradiaz2685-boop moradiaz2685-boop left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Factory

Comment thread internal/viewer/server.go

srv := &http.Server{
Addr: addr,
Handler: guarded,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revisado

{{end}}
</div>

<script>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Factory

});
el.innerHTML = html;
});
</script>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

,,,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants