探索

倒计时漏洞

时间:2010-12-5 17:23:32  作者:时尚   来源:娱乐  查看:  评论:0
内容摘要:去年冬天,我在一个抢购茅台的脚本里第一次注意到倒计时漏洞。页面显示“距开始还有 00:00:03”,我盯着那串数字跳完,手指悬在鼠标上,结果按钮根本没亮。刷新之后,库存已经没了。后来我翻了翻代码,发现

去年冬天,倒计洞我在一个抢购茅台的时漏脚本里第一次注意到倒计时漏洞。页面显示“距开始还有 00:00:03”,倒计洞我盯着那串数字跳完,时漏手指悬在鼠标上,倒计洞结果按钮根本没亮。时漏刷新之后,倒计洞库存已经没了。时漏后来我翻了翻代码,倒计洞发现前端倒计时用的时漏是本地时间,而服务器校验用的倒计洞是另一套时钟——两边差了将近两秒。这两秒,时漏就是倒计洞漏洞的温床。

倒计时这东西,时漏表面上是倒计洞给用户看的,实际上它是一份契约。你告诉用户“还有五秒”,用户就信这五秒。可很多系统在实现的时候,把倒计时当成纯展示组件,跟真正的业务逻辑脱钩。前端算它的,后端算它的,中间靠一个模糊的“差不多”来衔接。一旦有人能操纵本地时间,或者干脆绕过前端直接发请求,倒计时就成了一道摆设。

我见过最离谱的一个案例,是某在线考试系统。交卷倒计时显示在页面顶部,学生端用 JavaScript 每秒减一。但后端只在交卷请求里带了一个 remaining_time 字段,完全信任前端传上来的值。有个学生把系统时间调慢,倒计时跟着变慢,最后多做了四十分钟。监考老师那边看到的还是正常倒计时,因为老师端的计时器是独立跑的。两套时钟,两个真相。

这类漏洞的根源不复杂。开发者习惯把倒计时当作 UI 状态,而不是业务状态。UI 状态可以随便改,业务状态必须由服务端说了算。可偏偏有些场景下,服务端为了省事,把判断权下放了。比如“倒计时结束才能点击”这种逻辑,如果只靠前端按钮的 disabled 属性来控制,那跟没锁门有什么区别。

还有一种更隐蔽的,是倒计时结束后的竞态条件。比如秒杀场景,倒计时归零的瞬间,大量请求同时涌入。如果服务端没有做好幂等和排队,就会出现超卖。倒计时本身没坏,但它把所有人的注意力都引到了“零秒”那一刻,反而掩盖了后端处理的混乱。我见过一个系统,倒计时结束后按钮亮了,但点下去返回“活动已结束”。用户骂前端,前端骂后端,后端说时间没到。查了半天,是负载均衡后面两台服务器的系统时间差了三百毫秒。

怎么防?说穿了就一句话:倒计时可以给用户看,但决策必须由服务端做。服务端不信任任何客户端传来的时间,只认自己的时钟。前端倒计时可以继续跑,但每次关键操作都要带上服务端签发的时间戳或者 token,由服务端校验是否在有效窗口内。至于那些“倒计时结束才能操作”的交互,前端做一层拦截就够了,真正的门禁放在 API 网关或者业务逻辑层。

我后来在自己的项目里加了一条规矩:任何跟时间相关的判断,必须有一个服务端权威时间源。前端倒计时只是装饰,它跑得快了慢了,不影响业务。用户改本地时间?随他改。请求到了服务端,该拒绝就拒绝。倒计时漏洞说到底不是技术难题,是态度问题——你愿不愿意把“信任”收回来,放在自己手里。

最近更新
热门排行
copyright © 2026 powered by 力不从心网   sitemap