Skip to content

fix(community): OG 封面 referrerPolicy=no-referrer 规避微信防盗链裂图#316

Merged
longsizhuo merged 1 commit intomainfrom
fix/og-referrer-policy
Apr 19, 2026
Merged

fix(community): OG 封面 referrerPolicy=no-referrer 规避微信防盗链裂图#316
longsizhuo merged 1 commit intomainfrom
fix/og-referrer-policy

Conversation

@longsizhuo
Copy link
Copy Markdown
Member

症状

/feed 列表里微信公众号卡片封面显示裂图:"此图片来自微信公众平台未经允许不可使用"。

原因

微信 `mmbiz.qpic.cn` 对图片请求检查 Referer:

  • Referer 不是 `mp.weixin.qq.com` → 返回裂图
  • 不发 Referer → 放行(微信客户端打开文章时浏览器也不发 Referer,所以这是微信自己的兼容路径)

知乎 `pic*.zhimg.com` / 小红书 `ci.xiaohongshu.com` 同样策略。

改动

  • `LinkCard`: `` 加 `referrerPolicy="no-referrer"`
  • `/admin/community`: 原来的 `next/image` 换成 `` + `referrerPolicy`(顺手规避 next/image `remotePatterns` 对外站图床的白名单限制——Copilot CR 之前提过,当时靠 `unoptimized` 绕,现在统一切 `` 更干净)

验证

  • typecheck 0 errors
  • vitest 1/1 绿
  • 本地 dev 可在 `/feed` 看真实公众号卡片封面正常加载(有可测试数据的话)

微信 mmbiz.qpic.cn(以及知乎 pic* / 小红书 ci.xiaohongshu.com)对图片请求检查
Referer,非 mp.weixin.qq.com 来源直接返回"此图片来自微信公众平台未经允许不可
使用"的裂图。不发 Referer 时反而放行(微信客户端打开文章时浏览器也不发)。

改动:
- LinkCard: <img> 加 referrerPolicy="no-referrer"
- /admin/community: 原来的 next/image 改成 <img> + referrerPolicy
  (顺手规避 next/image remotePatterns 对任意外站域名的限制——Copilot CR 之前
   指出过,当时用 unoptimized 绕过,现在统一切 <img> 更干净)
Copilot AI review requested due to automatic review settings April 19, 2026 20:09
@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:09pm
website-preview Building Building Preview, Comment Apr 19, 2026 8:09pm

@longsizhuo longsizhuo merged commit 65293a0 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 fixes broken OG cover images in community link cards (e.g., WeChat public account covers) by preventing the browser from sending a Referer header, which avoids anti-hotlinking “裂图” responses.

Changes:

  • Add referrerPolicy="no-referrer" to OG cover rendering in the feed LinkCard.
  • Replace next/image with native <img> on /admin/community and add referrerPolicy="no-referrer" (also avoiding remotePatterns limitations).

Reviewed changes

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

File Description
app/feed/components/LinkCard.tsx Adds referrerPolicy="no-referrer" to OG cover <img> in feed cards.
app/admin/community/page.tsx Switches OG cover thumbnail from next/image to <img> and applies referrerPolicy="no-referrer".

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

Comment on lines 48 to 52
<img
src={link.ogCover}
alt={link.ogTitle ?? link.host}
referrerPolicy="no-referrer"
className="w-full aspect-[16/9] object-cover border-b border-[var(--foreground)]"
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.

link.ogCover 直接作为 <img src> 渲染,绕过了仓库里用于媒体 URL scheme 白名单的 sanitizeMediaUrl(lib/url-safety.ts 里明确要求后端/用户输入的媒体 URL 渲染前必须过白名单)。建议在渲染前先计算 const safeOgCover = sanitizeMediaUrl(link.ogCover),并仅在 safeOgCover 非空时渲染封面(否则走占位块)。

Copilot uses AI. Check for mistakes.
Comment on lines +139 to +143
<img
src={link.ogCover}
alt={link.ogTitle ?? link.url}
fill
sizes="160px"
className="object-cover"
unoptimized
referrerPolicy="no-referrer"
className="absolute inset-0 w-full h-full object-cover"
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.

这里把 OG 封面从 next/image 改为原生 <img> 后,link.ogCover 会以未校验的 URL 直接进入 src。仓库已有 sanitizeMediaUrl 用于拦截 javascript:/data: 等协议(lib/url-safety.ts),建议在渲染前对 link.ogCover 做白名单过滤,并在返回 null 时回退到占位内容。

Copilot uses AI. Check for mistakes.
longsizhuo pushed a commit that referenced this pull request Apr 19, 2026
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)
longsizhuo added a commit that referenced this pull request Apr 19, 2026
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)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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