构造反证问题的核心不是再找一条支持假设的线索,而是先写出“如果这个假设为真,哪个可观察结果必须出现、且无法被其他解释轻易说明”。在网站恶意代码检测里,最实用的做法是把假设转成一条可被证伪的预测,再设计一个能产生区分性证据的动作。若预测落空,就应降低该假设的优先级,而不是继续补证据。
假设你观察到:某类页面在搜索引擎中的抓取量下降,同时站内日志里出现了不常见的脚本请求。这个矛盾可以至少有两种解释。
这两个解释都能解释“抓取量下降”和“异常请求”同时出现。如果只继续找异常请求,只会让两个解释都显得成立。反证问题要做的,是找出一个只属于其中一个解释的预测。
对解释A,可以写出这样的预测:如果恶意脚本确实注入在页面输出中,那么同一URL在不同环境、不同用户代理或不同缓存状态下,返回的HTML主体应出现可复现的差异;并且这个差异应指向同一段脚本或同一外部资源。
对解释B,可以写出另一条预测:如果只是模板或第三方组件变更,那么异常请求应与某个已知变更时间点或某个公共组件版本相关,而不是与特定页面内容绑定;在回滚该变更后,异常请求应减少或消失。
这里的关键是:预测必须能落空。比如“页面可能有问题”不是预测;“某个URL在关闭缓存后仍返回同一段可疑脚本”才是预测。反证问题应围绕后者来写。
一个实际动作是:选取少量受影响URL和少量未受影响URL,在相同网络条件下分别请求,保存返回的HTML片段、响应头和请求时间,再与变更记录对照。这个动作的结果会直接影响下一步。
这个动作的价值不在于一次证明谁对谁错,而在于把“异常请求”从模糊线索变成可区分证据。只有能区分两个解释的证据,才值得进入下一步。
第三方估算流量、搜索引擎报告和站内统计的口径并不相同。抓取量下降可能来自抓取预算调整、站点结构变化、服务器响应变慢、robots规则变化,也可能只是报告延迟。它不能单独证明存在恶意代码,也不能单独排除恶意代码。
因此,反证问题里应避免写“抓取量下降,所以有恶意代码”。更稳妥的写法是:如果恶意代码是抓取量下降的原因,那么在移除或屏蔽该代码后,相关URL的抓取和渲染应出现可观察的恢复;如果移除后没有变化,就要重新考虑其他解释。这里的“恢复”只是假设比较方向,不承诺具体时间或幅度。
当你面对多个解释时,可以按下面四步写反证问题。
例如,假设“某页面被注入恶意代码”,预测“关闭缓存后仍返回同一段可疑脚本”,动作“固定请求条件并保存HTML”,决策“若预测成立则隔离脚本;若不成立则优先检查公共组件和缓存分流”。这样写出的反证问题,才能帮助你在网站恶意代码检测中减少无效排查。