Skip to content

fix(community): CR fixes — 嵌套按钮 + OG 封面 URL sanitize#317

Merged
longsizhuo merged 1 commit intomainfrom
fix/cr-feedback
Apr 19, 2026
Merged

fix(community): CR fixes — 嵌套按钮 + OG 封面 URL sanitize#317
longsizhuo merged 1 commit intomainfrom
fix/cr-feedback

Conversation

@longsizhuo
Copy link
Copy Markdown
Member

收尾 Copilot 在 #315 / #316 上留的两条 CR:

  1. Hero.tsxfix(community): ShareLink 按钮语义修正 + feed SSR 抗 CF 挑战 #315 CR):`` 嵌套交互元素,HTML 无效 + 键盘/a11y 问题 → 把 `` 直接渲染成按钮样式
  2. LinkCard.tsx / admin/community/page.tsxfix(community): OG 封面 referrerPolicy=no-referrer 规避微信防盗链裂图 #316 CR):OG 封面 URL 直接进 ``,用仓库已有的 `sanitizeMediaUrl` 兜底拦 `javascript:/data:`(defense-in-depth,后端 UrlNormalizer 是第一道)

typecheck 0 errors。

Copilot CR 指出的两条:

PR #315 Hero.tsx:119 —— <a> 包 <button> 是嵌套交互元素(HTML 无效 + a11y 问题)
  修法:把 <Link> 直接渲染成按钮样式,不再嵌套 <button>

PR #316 LinkCard.tsx:52 / admin/community/page.tsx:143 —— OG 封面 URL
  直接进 <img src> 没过白名单。
  修法:用 lib/url-safety.ts 的 sanitizeMediaUrl 兜底,拦 javascript:/data: 协议
  (后端 UrlNormalizer 是第一道防线,前端 sanitize 是 defense-in-depth)
Copilot AI review requested due to automatic review settings April 19, 2026 20:19
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 19, 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 Apr 19, 2026 8:19pm
website-preview Building Building Preview, Comment Apr 19, 2026 8:19pm

@longsizhuo longsizhuo merged commit 9842760 into main Apr 19, 2026
4 of 6 checks passed
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 addresses outstanding code review feedback in the community/feed UI by fixing invalid nested interactive elements in the homepage Hero CTAs and adding defense-in-depth URL sanitization for OG cover images before rendering them into <img src>.

Changes:

  • Refactors Hero CTAs to avoid invalid <a><button/></a> nesting by styling <Link> elements directly as button-like CTAs.
  • Sanitizes OG cover image URLs with sanitizeMediaUrl before using them in <img src> in both feed cards and the admin moderation page.
  • Keeps referrerPolicy="no-referrer" behavior for hotlink-protected image hosts (WeChat/Zhihu/etc.).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
app/feed/components/LinkCard.tsx Sanitizes ogCover before rendering into <img src> for feed cards.
app/components/Hero.tsx Removes nested <button> inside <Link> and applies button styles to the link itself.
app/admin/community/page.tsx Sanitizes ogCover before rendering into <img src> in the admin review list.

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

Comment on lines 29 to 33
export function LinkCard({ link, categoryLabel, isLoggedIn }: LinkCardProps) {
const t = useTranslations("feed.card");
// defense-in-depth:过白名单协议拦 javascript:/data:,后端 UrlNormalizer 是第一道,这里是第二道
const safeOgCover = sanitizeMediaUrl(link.ogCover);

Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

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

LinkCard now sanitizes link.ogCover, but the card’s main <a href={link.url}> still uses a backend-provided URL without going through sanitizeExternalUrl. Since url-safety.ts documents that any backend/user-provided URLs must be sanitized before rendering, this remains an XSS vector (e.g., javascript:). Consider sanitizing link.url and rendering the card as non-clickable (or fallback to text) when the URL is unsafe.

Copilot uses AI. Check for mistakes.
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