实战指南

技术栈检测Audit

技术栈检测实战指南:用一个 URL 读懂一个站点的技术栈

技术栈栈识别调研竞品分析审计
Senrok Team
作者Senrok Team
发布于

在动手针对一个站点做任何工作之前,一位资深工程师做的第一件事就是知道那个页面"实际"跑在什么上面。迁移计划、安全审计、竞品拆解、合作伙伴对接——每一件事都从同一个问题开始:这玩意儿建在什么之上?

Stack Scanner 是这个问题的快速答案。本指南是它的操作手册:指纹匹配的实际原理、HTML-only 检测能看和不能看什么、以及如何在不"过度信任"的前提下读懂置信度标签。

Scanner 怎么工作

Scanner 通过我们的 CORS 代理抓取 URL,解析 HTML 响应,再把结果对一个手工维护的指纹库做模式匹配。每条指纹都是一个能指向某项技术的具体模式——一个 <meta name="generator"> 的值、一段带已知路径的 script 标签、一个 class 前缀、一个 CSS 变量名、一个指向已知 CDN 的 <link>

对每条匹配,Scanner 报告三件事:

  1. 检测到的技术。
  2. 分类——CMS、Framework、Analytics、Hosting / CDN、JavaScript library、Marketing 或其他。
  3. 置信度标签——高、中、低。

匹配是确定性的。同样的输入产生同样的输出。链路里没有 LLM,没有基于 token 重叠的模糊匹配,也没有从间接信号做推断。模式在指纹库里且在 HTML 里,就报;不在,就不报。

置信度标签,如实解释

置信度不是概率。它是一个分类标签,对应一件具体的事:

  • ——两个或以上独立强信号同时匹配。一个 meta 标签、一段 script 标签、一个 CSS class 同时指向同一个栈,就是高。不用额外验证就能据此行动。
  • ——一个强信号匹配。模式在指纹库里也在 HTML 里,但没第二个信号确认。可以据此行动,但值得快速抽检一下。
  • ——一个弱信号匹配。模式跨多个技术都常见(一个 class 前缀、一个通用脚本名),不能唯一定位栈。把它当提示,不当成结论。

每条匹配下面的 Evidence 行展示的是触发检测的那一段具体模式。读它。如果 evidence 是 <meta name="generator" content="WordPress 6.4.2">,这是高置信检测。如果 evidence 是 class="jsx-abcdef",信号就弱,标签是合理的低。

Scanner 能看什么

Scanner 能看到 HTML 响应里的任何东西——服务器返回的静态 markup,包括:

  • <meta> 标签(generatorapplication-nametheme-color
  • <link> 标签(manifest、样式表、对已知 CDN 的 preconnect)
  • <script> 标签(分析、标签管理器、框架 bundle、第三方 widget)
  • CSS class 名和内联样式
  • <html> 属性(data-* 属性、根元素上的 class
  • HTML 注释(一些工具在构建注释里自报家门)
  • 内联 JSON 配置块(Next.js、Nuxt、Gatsby 都会发一段)
  • Open Graph 和 Twitter Card meta 标签

Scanner 也能看到内联 JSON 配置块里的内容——比如 Next.js 会发一个 __NEXT_DATA__ script 标签,经常能识别构建版本。Gatsby 站点会发一个 ___gatsby 全局。这些都在 HTML 可见,所以能被扫到。

Scanner 不能看什么

这是操作员最容易过度信任的部分。Scanner 是 HTML-only。它看不到:

  • 源站的响应头——ServerX-Powered-BySet-Cookie、自定义平台头。代理发请求,所以 Scanner 看到的是代理的响应头,不是源站的。Web 服务器、语言运行时、边缘平台通常都不可见。
  • 客户端 hydration——HTML 响应之后由 JavaScript 渲染出来的任何东西。如果一个框架 hydrate 了一个 SPA,Scanner 看到的是 bootstrap HTML,不是渲染后的 DOM。
  • 登录后的页面——代理发的是未认证请求。登录墙后面的页面会返回登录表单,而不是页面内容。
  • 需要认证或 cookie 的子资源——如果页面是受控的,子资源也受控。Scanner 报告的是"门",不是"门后"。
  • API 响应——客户端应用 hydration 之后获取的任何东西。Scanner 看到的是 bootstrap fetch,不是后续的 XHR。
  • JavaScript 跑完之后的 DOM——同理,任何只存在于渲染后 DOM 里的东西。SPA 特有的运行时特性(路由 handler、hydration marker)都不可见。

实际效果:对于营销站、内容站、传统 CMS 驱动的页面,Scanner 是准的。对于 SPA 和登录后应用,Scanner 看到的是前门,不是房子。

什么时候跑

Scanner 真正值钱的四个时机:

  1. 迁移范围讨论会之前——确认栈确实是你被告知的那个,并把团队忘记提的东西挖出来。
  2. 安全审计之前——知道要查哪些 header 和运行时特性,以及哪些 CMS 插件很可能在范围内。
  3. 合作伙伴对接之前——确认对方 API 从浏览器可达,并发现你可能踩到的第三方 SDK。
  4. 竞品拆解——知道竞品跑的 CMS、框架、分析栈,并发现迁移信号(新的框架版本、新的分析供应商)。

不要把它当监控检查跑。Scanner 是一次性审计,不是持续监控。栈变化是慢的;大多数站点一季度一次就够了。

如何读懂输出

结果页有三个区:分类汇总、检测到的技术列表、每条匹配的 evidence。看的时候请记住几件事:

  • "无结果"本身就是个发现。 它可能意味着站点用了自定义栈,也可能只是指纹库还没收录。这里的信号是"我们指纹不出来",不是"这站没栈"。
  • CMS 上的高置信是可执行的。 Cloudflare 上的高置信不是(Cloudflare 从 header 检测,我们看到的是代理不是源站,信号不可靠)。按你问题关心的分类去筛。
  • "Hosting / CDN" 分类噪声最大,因为 Scanner 只能看到代理,看不到源站边缘。把这个分类读成"代理托管在 X 上",而不是"站点托管在 X 上"。
  • 营销标签和分析是最准的,因为它们按设计就在 HTML 里。如果 Scanner 报了 HubSpot 或 Segment,这是可靠的。

常见模式与其含义

反复出现的一组检测模式:

  • Next.js + Vercel + Segment + HubSpot——现代 B2B SaaS 营销站,边缘平台上 SSR。__NEXT_DATA__ blob 是决定性证据。
  • WordPress + Yoast + MonsterInsights——有较长历史的内容站。wp-content 路径和 yoast JSON-LD block 是指纹。
  • Shopify + Klaviyo + Google Analytics——DTC 电商站。cdn.shopify.com script 和 shopify-features body class 是信号。
  • Astro + Cloudflare + Plausible——边缘平台上的现代 static-first 站点。astro- data 属性和 /_astro/ script 路径是指纹。
  • Webflow + Mixpanel——设计驱动的站点带产品分析。webflow- data 属性和 mixpanel.init script 是信号。

这些是模式,不是规则。Scanner 报技术,含义由你来判断。

什么时候该升级到自建系统

如果你一周跑 Scanner 超过几次,就到了一个自建系统更划算的临界点。几个信号:

  • 你需要审计登录后页面,代理做不到。
  • 你需要看源站的响应头,代理隐藏了。
  • 你需要审计 hydration 后的 SPA 页面,这要无头浏览器而不是 HTML fetch。
  • 你需要跟踪栈随时间的变化,不是一次性审计。
  • 你需要检测不在公开指纹库里的内部工具。

上述任何一种情况下,对的解法是一套对接你自己基础设施的自定义栈检测系统,带着你实际需要的 header、认证和信号跑。免费 Scanner 是合适的起点,不是终局。


Scanner 地址:/tools/stack-detector。任何迁移、审计、集成对话之前对 URL 跑一次。代理每次扫描只发一次 fetch;除了你提交的 URL,没有任何数据被存储或发给第三方。