Skip to content

fix(posts-cr): Copilot CR fixes — XSS narrowing, bundle split, satoken guard#352

Merged
longsizhuo merged 1 commit into
mainfrom
fix/posts-cr
May 24, 2026
Merged

fix(posts-cr): Copilot CR fixes — XSS narrowing, bundle split, satoken guard#352
longsizhuo merged 1 commit into
mainfrom
fix/posts-cr

Conversation

@longsizhuo
Copy link
Copy Markdown
Member

Summary

  • PostContent.tsx: narrow style attribute in rehype-sanitize from * (all elements) to span/svg only — KaTeX only needs style on these two; allowing global style is a CSS injection vector in UGC content
  • lib/frontmatter.ts (new): extract buildFrontmatter out of EditorPageClient.tsx so detail page and card bundles no longer pull in the entire editor stack
  • PostDetailOwnerActions.tsx: add .catch(()=>({})) on DELETE res.json() for resilient error body parsing (mirrors existing deleteEvent pattern in admin/events/lib.ts)
  • EditorPageClient.tsx: align titleToSlug comment with actual Unicode behavior; add tags.map(t=>t.trim()).filter(Boolean) before POST; guard satoken header so empty token throws a clear error instead of sending empty header
  • PromoteToDocsButton.tsx: update buildFrontmatter import path; guard satoken header on promote POST

Test plan

  • pnpm build passes (TypeScript + 51 vitest tests + prebuild checks)
  • Route table unchanged — no regression on SSG/Dynamic classification
  • Manual: verify KaTeX renders correctly in PostContent (style still allowed on span/svg)
  • Manual: verify promote flow opens GitHub with correct frontmatter
  • Manual: verify DELETE error shows proper message when backend returns non-JSON

Fixes Copilot CR feedback on PR #350.

🤖 Generated with Claude Code

- PostContent: narrow rehype-sanitize style attribute from * to span/svg only
  (KaTeX only needs style on these two elements; global style is an XSS vector)
- Extract buildFrontmatter to lib/frontmatter.ts to avoid pulling editor
  bundle into detail page / card bundles
- PostDetailOwnerActions: add .catch(()=>({})) on DELETE res.json() for
  resilient error body parsing
- EditorPageClient: align titleToSlug comment with actual Unicode behavior,
  add tags trim+filter before POST, guard satoken header to avoid empty token
- PromoteToDocsButton: update import path, guard satoken header

Co-authored-by: copilot-pull-request-reviewer[bot] <198982749+copilot-pull-request-reviewer[bot]@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 24, 2026 17:28
@vercel
Copy link
Copy Markdown

vercel Bot commented May 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
involutionhell-github-io Building Building Preview, Comment May 24, 2026 5:29pm
website-preview Building Building Preview, Comment May 24, 2026 5:29pm

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR applies follow-up fixes to the lightweight posts feature: tightening UGC sanitization to reduce XSS/CSS-injection surface area, splitting buildFrontmatter into a standalone module to avoid pulling editor code into other bundles, and improving client request robustness (token handling + non-JSON error bodies).

Changes:

  • Narrow rehype-sanitize’s style allowance from global to KaTeX-required elements only (span/svg).
  • Extract buildFrontmatter into lib/frontmatter.ts and update imports to reduce bundle coupling.
  • Harden client fetch flows: guard empty satoken, trim/filter tags prior to POST, and tolerate non-JSON DELETE error bodies.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
lib/frontmatter.ts New shared buildFrontmatter helper to decouple editor bundle from promote/detail UI.
app/components/PromoteToDocsButton.tsx Switch to shared buildFrontmatter; adjust satoken header handling for promote POST.
app/components/PostContent.tsx Tighten sanitize schema: restrict style attribute to KaTeX-needed elements.
app/[locale]/u/[username]/posts/[slug]/PostDetailOwnerActions.tsx Make DELETE response parsing resilient to non-JSON bodies; adjust auth header emission.
app/[locale]/editor/EditorPageClient.tsx Update slug comment, normalize tags, and add clearer token guard for publish requests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/frontmatter.ts
Comment on lines +4 to +5
* 抽到独立模块的原因:EditorPageClient 和 PromoteToDocsButton 都需要它,
* 把它留在 EditorPageClient.tsx 会让详情页/卡片 bundle 拖进整个编辑器栈。
Comment on lines +59 to 63
headers: { ...(token ? { satoken: token } : {}) },
});
const body = (await res.json()) as ApiResponse<void>;
const body = (await res.json().catch(() => ({}))) as ApiResponse<void>;
if (res.ok && body.success) {
router.replace(`/u/${authorUsername}/posts`);
Comment on lines 114 to +118
method: "POST",
headers: {
"Content-Type": "application/json",
// rewrite 透传:后端读 satoken,不是 x-satoken
satoken: token,
// rewrite 透传:后端读 satoken,不是 x-satoken;空 token 不发 header
...(token ? { satoken: token } : {}),
@longsizhuo longsizhuo merged commit c5f37fa into main May 24, 2026
6 of 8 checks passed
@longsizhuo longsizhuo deleted the fix/posts-cr branch May 24, 2026 17:37
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.

2 participants