Skip to content

fix(server): allow inline styles in CSP so web math renders on non-loopback binds - #1847

Merged
wbxl2000 merged 2 commits into
mainfrom
fix/csp-inline-styles-math
Jul 17, 2026
Merged

fix(server): allow inline styles in CSP so web math renders on non-loopback binds#1847
wbxl2000 merged 2 commits into
mainfrom
fix/csp-inline-styles-math

Conversation

@wbxl2000

Copy link
Copy Markdown
Collaborator

Related Issue

N/A — clear, reproducible bug with a focused fix; the problem is explained below.

Problem

When the server binds a non-loopback address (web UI accessed over LAN or a reverse proxy), LaTeX formulas in the chat render as garbled, overlapping characters.

Root cause: the security CSP sent on non-loopback binds is default-src 'self'; … with no style-src, so style handling falls back to default-src 'self' and the browser strips inline style="…" attributes from injected markup. KaTeX output (rendered by the markdown renderer and injected via innerHTML) carries essentially all glyph positioning — vertical stacking, offsets, delimiter sizing — in inline style attributes (a single fraction formula contains ~68 of them), so formulas collapse into overprinted glyphs. Shiki code highlighting (inline colors) and Mermaid diagrams (inline <style> in the SVG) are degraded by the same mechanism. Loopback binds get no CSP header at all, which is why local development never surfaces this.

What changed

  • Add style-src 'self' 'unsafe-inline' to the non-loopback CSP. Only styles are relaxed — script execution stays strictly restricted — which is the standard CSP posture for generated markup such as KaTeX/Shiki/Mermaid output. This restores math rendering, code-highlight colors, and Mermaid styling on network-served deployments.
  • New regression test for the security-headers hook (CSP allows inline styles, keeps inline scripts forbidden, HSTS only with TLS); updated the two exposure tests that assert the CSP string.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

…opback binds

The security CSP fell back to default-src 'self' for styles, which strips
the inline style attributes that KaTeX (injected via innerHTML) uses for
all glyph positioning — formulas collapsed into overlapping characters on
any non-loopback-served web UI. Shiki highlighting and Mermaid diagrams
hit the same mechanism. Add style-src 'self' 'unsafe-inline'; scripts
remain strictly restricted.
@changeset-bot

changeset-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f3aa87c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dd79ebbb53

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

await hook({} as never, reply as never, 'payload');
const csp = headers.get('content-security-policy');
expect(csp).toContain("style-src 'self' 'unsafe-inline'");
expect(csp).not.toContain("script-src 'self' 'unsafe-inline'");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Assert the effective policy that forbids inline scripts

This negative substring check does not prove the behavior named by the test. If the policy later becomes default-src 'self' 'unsafe-inline', both this assertion and the following default-src 'self' assertion still pass even though inline scripts are then allowed through fallback; explicit variants such as script-src 'unsafe-inline' also evade this exact substring. Parse the directives and assert that the effective script-src (or its default-src fallback) excludes 'unsafe-inline'.

Useful? React with 👍 / 👎.

@pkg-pr-new

pkg-pr-new Bot commented Jul 17, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@f3aa87c
npx https://pkg.pr.new/@moonshot-ai/kimi-code@f3aa87c

commit: f3aa87c

A negative substring check only rejects one exact string: default-src
gaining 'unsafe-inline' (inline <script> allowed via fallback) or an
explicit script-src 'unsafe-inline' would both slip through. Parse the
directives and assert the effective script policy (script-src, falling
back to default-src) excludes 'unsafe-inline'/'unsafe-eval'/data:.
@wbxl2000

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: f3aa87c7c9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@wbxl2000
wbxl2000 merged commit 56ba8e0 into main Jul 17, 2026
14 checks passed
@wbxl2000
wbxl2000 deleted the fix/csp-inline-styles-math branch July 17, 2026 12:21
@github-actions github-actions Bot mentioned this pull request Jul 17, 2026
7723qqq pushed a commit to 7723qqq/kimi-code that referenced this pull request Jul 17, 2026
…opback binds (MoonshotAI#1847)

* fix(server): allow inline styles in CSP so web math renders on non-loopback binds

The security CSP fell back to default-src 'self' for styles, which strips
the inline style attributes that KaTeX (injected via innerHTML) uses for
all glyph positioning — formulas collapsed into overlapping characters on
any non-loopback-served web UI. Shiki highlighting and Mermaid diagrams
hit the same mechanism. Add style-src 'self' 'unsafe-inline'; scripts
remain strictly restricted.

* test(server): assert the effective script-src in the CSP regression test

A negative substring check only rejects one exact string: default-src
gaining 'unsafe-inline' (inline <script> allowed via fallback) or an
explicit script-src 'unsafe-inline' would both slip through. Parse the
directives and assert the effective script policy (script-src, falling
back to default-src) excludes 'unsafe-inline'/'unsafe-eval'/data:.
7723qqq pushed a commit to 7723qqq/kimi-code that referenced this pull request Jul 17, 2026
…opback binds (MoonshotAI#1847)

* fix(server): allow inline styles in CSP so web math renders on non-loopback binds

The security CSP fell back to default-src 'self' for styles, which strips
the inline style attributes that KaTeX (injected via innerHTML) uses for
all glyph positioning — formulas collapsed into overlapping characters on
any non-loopback-served web UI. Shiki highlighting and Mermaid diagrams
hit the same mechanism. Add style-src 'self' 'unsafe-inline'; scripts
remain strictly restricted.

* test(server): assert the effective script-src in the CSP regression test

A negative substring check only rejects one exact string: default-src
gaining 'unsafe-inline' (inline <script> allowed via fallback) or an
explicit script-src 'unsafe-inline' would both slip through. Parse the
directives and assert the effective script policy (script-src, falling
back to default-src) excludes 'unsafe-inline'/'unsafe-eval'/data:.
ywh114 pushed a commit to ywh114/kimi-code that referenced this pull request Jul 19, 2026
…opback binds (MoonshotAI#1847)

* fix(server): allow inline styles in CSP so web math renders on non-loopback binds

The security CSP fell back to default-src 'self' for styles, which strips
the inline style attributes that KaTeX (injected via innerHTML) uses for
all glyph positioning — formulas collapsed into overlapping characters on
any non-loopback-served web UI. Shiki highlighting and Mermaid diagrams
hit the same mechanism. Add style-src 'self' 'unsafe-inline'; scripts
remain strictly restricted.

* test(server): assert the effective script-src in the CSP regression test

A negative substring check only rejects one exact string: default-src
gaining 'unsafe-inline' (inline <script> allowed via fallback) or an
explicit script-src 'unsafe-inline' would both slip through. Parse the
directives and assert the effective script policy (script-src, falling
back to default-src) excludes 'unsafe-inline'/'unsafe-eval'/data:.
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.

1 participant