结论是有条件的:当访客被分配到不同页面版本时,先不要急着把差异归因于木马,而要先确认两件事——你采集的样本是否来自同一入口路径,以及每个样本对应的响应是否在时间上可比。如果这两点无法成立,样本污染就比真实感染更可能是解释。下面给出可操作的判断顺序。
访客被分配到不同版本,常见来源有三类:一是站点本身做了 A/B 测试或灰度发布,不同用户命中不同模板;二是 CDN 或反向代理缓存了不同时间点的响应;三是木马确实只对部分访客注入内容。前两类属于分发与缓存造成的差异,第三类才是需要检测工具重点排查的对象。
判断的关键不是“版本不同”,而是“同一个请求条件是否稳定复现”。如果你在相同 UA、相同 IP 段、相同路径下反复请求,得到的响应仍然随机跳变,那更接近分发层或缓存层的问题;如果只在特定 UA 或特定来源下出现异常,才更值得怀疑注入。
实际操作上,可以先用 curl -I 或浏览器无痕模式,对同一 URL 连续请求多次,记录每次响应中的关键标记:状态码、Content-Length、ETag、Last-Modified、以及页面中是否有额外脚本。假设你连续请求 10 次,其中 7 次返回正常页面,3 次多出一段外部脚本,那么这 3 次是否来自同一缓存节点或同一 UA,就是下一步要验证的分叉点。
如果多次请求结果一致,说明当前入口没有随机分配;如果结果不一致,就要把“不一致”本身当作证据,而不是直接当作感染证据。此时下一步动作是固定一个变量再测:先固定 UA,再固定来源 IP 段,最后固定请求时间窗口。每固定一个变量,观察异常是否消失。消失的那个变量,往往就是污染来源。
很多“不同版本”其实是缓存副本造成的。CDN 节点、服务端缓存、甚至浏览器缓存,都可能让不同访客拿到不同时间的页面。检测工具如果只扫描单一节点,就可能把缓存差异误报为木马注入。
可行的验证方式是:直接回源请求,绕过 CDN 和缓存层,看响应是否仍然异常。如果回源正常、经过 CDN 异常,问题更可能在缓存或分发配置;如果回源也异常,才需要继续查服务端文件与数据库。这里要注意,回源请求本身也可能被缓存,所以最好带上随机查询参数或禁用缓存的请求头,但不要依赖单一参数就下结论。
上面的判断有一个重要反例:如果木马本身就以“按访客特征分发”为设计目标,那么固定变量后异常可能仍然存在,甚至只在特定条件下触发。此时“回源正常”并不能排除感染,因为注入可能发生在回源之后的模板渲染或数据库读取阶段。
遇到这种情况,不能只靠请求层证据,而要转向文件与数据库比对:检查模板文件、插件目录、数据库中的选项表或文章内容是否被插入额外脚本。假设你发现某个模板文件在修改时间上明显晚于其他文件,且内容中包含不属于原主题的脚本引用,那么这比“访客版本不同”更接近直接证据。但修改时间本身也可能因正常更新而变化,所以需要结合版本控制或备份记录来确认。
当你已经能稳定复现异常响应时,下一步不是立刻全站清理,而是先做一次最小范围的隔离验证:
这样做的结果是:你能把“访客被分配到不同版本”拆成可验证的条件分支,而不是在感染与缓存之间反复猜测。只有当一个条件分支能稳定复现、且回源与文件层证据一致时,才适合进入清理阶段。