二维码安全:动态码风险与短链陷阱

2026-04-13发布 7分钟阅读

摘要 (TL;DR)

几周前我在一家咖啡厅扫桌上的菜单二维码,结果跳到了一个陌生的 ql.st 短链。仔细看才发现原来的二维码上贴了一张干净的新贴纸。老板说已经贴了好几周,没人察觉。“攻击”二维码格式本身的精巧漏洞几乎不存在——真实事件几乎都从一张贴纸开始。这篇文章会尊重这个现实:二维码安全的大头是纸、胶带、还有你两年前选定的那个 URL。

二维码不是一种安全原语。它是一个字符串的视觉编码,通常是 URL,安全性几乎完全取决于目的 URL 和生成方式。静态二维码直接装入最终 URL,印好后无法更改。动态二维码装入一个短的重定向 URL,通过提供商可以随时改目的地——很方便,但也带来长期风险:如果重定向服务关停、易主或被入侵,所有扫码者都会跟着新的目的地走。短链服务有同一类问题(过期、被劫持、追踪),所以不适合那些需要长期工作的公开印刷材料。一个稳妥的默认是把自己域名上的标准 URL 直接编码进静态二维码,把动态码或短链留给那些你已明确规划好生命周期的短期营销活动。

背景与概念

二维码的正式规范是 ISO/IEC 18004。版本从 1 到 40,版本越高模块(格子)越多,能承载更多数据。每个二维码都会附带一定量的 Reed-Solomon 纠错数据,分四个等级:

  • L:可恢复约 7%
  • M:可恢复约 15%
  • Q:可恢复约 25%
  • H:可恢复约 30%

提高纠错等级能让脏污、折痕或 logo 覆盖一部分时仍能扫描,但模块密度也会上升,所以印得很小时反而更难扫。名片、海报通常默认 M;如果中间要叠 logo,再考虑 Q 或 H。

静态二维码把最终 URL 直接埋在模块里,扫描结果是永久的。动态二维码埋的是一个短的重定向 URL,依赖一个能改目的地的提供商。这种灵活性既是它的特性,也是它长期风险的来源。

还有容量这个角度。Version 1(21×21 模块)在 M 纠错下大约能装 25 个字母数字字符;Version 10(57×57 模块)能装 300 个字符以上。长 URL 把你推到更高版本,密度上升,小尺寸下更难扫。动态码的短重定向确实印面更小,但这种紧凑是用长期依赖换来的。如果你真正关心的目的地能在自己域名内做短链(比如 example.com/p/123),就能在不外包重定向的前提下拿到大部分体积收益。

另一个相关概念是静默区(quiet zone)。扫描器依赖二维码周围一圈空白边——通常 4 个模块宽。如果版面把静默区压缩了来省空间,即便码本身完好,扫描也会变得不稳。设计师说”二维码扫不出来”时,第一个要看的就是静默区。

对比与数据

维度静态二维码动态二维码
编码的 URL最终目的 URL短重定向 URL
扫描追踪 / 分析默认没有标配功能
过期风险只要你保住域名就没有取决于服务方计划、合同、生命周期
第三方依赖没有重定向服务
钓鱼面积只需审查目的 URL重定向被入侵或易主时目的地会悄悄变
印好后可改不行,必须重印可以

短 URL 在印刷上确实看起来干净,但用户没法在视觉上验证它指向哪里。这正是攻击者利用的属性——你拿一点点美观换一大类风险。

实战场景

场景 1 — 名片、海报。最近我从一张 2019 年的名片上扫了二维码,那个 bit.ly 目的返回 404,估计是公司重组时短链计划失效了。把自己域名上的标准 URL 编码到静态二维码里。印刷品常常流通好几年,重定向依赖很少能撑过炒作周期或公司重组。小尺寸印刷时,降低纠错等级、缩短 URL 来减少模块数量,扫描可靠性才能上去。

场景 2 — 营销活动效果衡量。我认识的一家创业公司在展会上用了某流行动态码服务,三个月后免费版悄悄停掉了他们依赖的功能,所有发出去的实物物料都开始跳转到”计划已过期”页面。如果追踪本身就是目的,可以选信誉好的动态码提供商,或用静态码指向带 UTM 参数的 URL。我现在默认用自己托管的短链路径,比如 yourdomain.com/go/summer-2026:只要你拿着域名,就没有过期时钟。即便仍选择第三方动态码,也要写好停服计划:活动结束后重定向去哪儿,由谁负责。

场景 3 — 文档完整性与验证。不只放 URL,可以把文档哈希带签名的 URL 参数(如 ?d=abc123&sig=...)放进去,扫描后能确认与原件一致。我参与过一个证书项目,把 SHA-256 前 16 位十六进制加上 HMAC 签名打进二维码,结果版本被推到 10+,还得重新平衡印刷尺寸和扫描可靠性。这对合同、证书、产品标签等需要防篡改检测的场景很有用。

**场景 4 — 餐厅菜单与公共自助终端。**2020 年后菜单二维码大爆发,让公共场所成了贴纸钓鱼的肥沃土壤:攻击者印一张外观相似的二维码贴在原码上,毫无戒心的食客就被引到一个收集凭据的页面。防御措施很无聊但有效:把码层压固定到稳定表面、每天巡检、用餐厅自家域名的标准 URL,让真去看预览的客人能认出来。

常见误解

“二维码可以被黑掉。“格式本身通常不是薄弱环节。真正的风险是编码进去的 URL 是钓鱼或恶意路径,以及物理篡改——有人在公开场所把一张新二维码贴纸贴到你的原码上。眼检公开张贴的码是否被加贴是基本的物理安全习惯。

**“短 URL 更干净所以更好。“**视觉上是干净,但用户没法验证,背后服务可能关停或被入侵,二维码本身就成了对第三方的长寿依赖。长寿命的印刷材料里,自家域名的长 URL 更稳。

**“纠错等级越高越好。“**H 等级方便覆盖中间放 logo,但模块密度上升,小尺寸印刷下反而扫描可靠性变差。M 通常是个安全默认。

**“看二维码就能知道去哪。“**iOS 17、18 自带相机会先显示 URL 横幅,但有些 Android OEM 相机和第三方扫描器会一点就直接跳浏览器。伪装成公共 Wi-Fi 登录的钓鱼二维码就专门盯这种自动打开。能关掉自动打开就关掉,养成扫描后先确认域名再点的习惯。

**“我自己生成的二维码自动安全。“**如果你是通过某个会记录每次输入的第三方网页服务生成的,就不一定。一些免费二维码生成器会保存提交的 URL 转售分析,或在你的 URL 外面悄悄包一层自家重定向以追踪扫描。先看隐私声明,或在完全跑在浏览器里的工具里生成。

**“编码就是加密。“**二维码是编码不是加密。任何带扫描器的人都能读到编码内容,条形码也是同理。如果需要保密,先加密再编码——比如编码一个签名的 JWT,而不是可读的参数。

决策清单

  1. 这个二维码需要工作多久?
    • 数年以上 → 优先静态二维码 + 自家域名 URL
    • 短期活动 → 动态码或 UTM 参数都合理。
  2. 真的需要追踪吗?
    • 不需要 → 静态码足够。
    • 需要 → 选信誉好的动态码提供商,且规划好停服后的重定向。
  3. 印刷尺寸多大?
    • 非常小 → 短 URL,纠错用 M。
    • 常规到大 → 想叠 logo 可用 Q 或 H。
  4. 会贴在公共场所吗?
    • 是 → 定期巡检是否被加贴或覆盖。
  5. 目的 URL 安全吗?
    • 确认 HTTPS、域名归属、当前是否仍有效。
  6. 二维码在哪里生成?
    • 优先离线或浏览器内生成,让编码的 URL 不会作为日志条目流到第三方网站。
  7. 二维码失效时怎么办?
    • 设计回退:在码旁边再印一行短 URL 或人类可读的提示,扫描器误读或目的地暂时离线时材料仍可用。

相关工具

Patrache Studio 二维码生成器 在浏览器里生成码,所以你输入的 URL 不会发往外部服务器。如果二维码会嵌入图像发到 Web 上,搭配 图像压缩完全指南 的格式建议;如果二维码最终要随一叠文档分发,按 浏览器 PDF 合并/拆分的安全收益 的流程合并文档,整个管线(从素材到成品 PDF)都能保持一致的隐私边界。

参考资料