PHP 7.3 无原生时间戳漏洞,但业务层误用 time()、strtotime()、JWT exp/nbf、date() 命名、客户端 timestamp 等易引发绕过、重放、覆盖、遍历等风险,需服务端强校验、统一时区、禁用客户端时间输入。

PHP 7.3 本身不自带“时间戳漏洞”,但某些业务逻辑在使用时间相关函数时,若设计不当,容易因时间处理缺陷引发安全或功能异常问题。这类问题常被称作“时间戳漏洞”,实际是业务层对时间校验、生成、比较或缓存策略的误用,而非 PHP 解释器本身的缺陷。
以下几类业务场景在 PHP 7.3 环境中最易触发时间戳相关风险:
订单/优惠券有效期校验逻辑
许多电商、营销系统依赖 time() 或 strtotime() 判断活动是否生效、券是否过期。若直接用用户可控参数(如 ?expire_time=1734850000)参与比对,且未做服务端强校验,攻击者可篡改时间戳绕过限制。
- 常见错误写法:
if ($_GET['expire_time'] > time()) { allow(); } - 正确做法:仅接受服务端生成的签名时间窗口(如 JWT exp 字段 + 服务端验证),或使用固定有效期配置(如
date('Y-m-d H:i:s', strtotime('+7 days'))),禁止客户端传入原始时间戳参与核心判断。
JWT 或 Token 的签发与验签流程
PHP 7.3 中若使用 firebase/php-jwt 等库,但未严格校验 nbf(not before)、exp(expires at)字段,或忽略时钟偏移(leeway 设置过大),会导致过期 Token 仍被接受。
- 风险点:
$token->setExpiration(time() + 3600)+ 客户端伪造exp值;或服务器时间不同步未设合理 leeway(如设为 300 秒以上)。 - 建议:启用
JWT::setLeeway(60)并确保所有节点 NTP 同步;exp必须由服务端生成并签名,不可由前端计算后传入。
文件上传/日志归档的命名与清理策略
部分系统用 date('YmdHis') 生成临时文件名或日志前缀,若并发高且未加随机因子,可能产生重复文件名覆盖,或被预测路径导致信息泄露(如 /logs/20261022153000_access.log)。
- 更严重的是:用时间戳作为唯一凭证(如
?file=report_20261022.zip)且无访问控制,攻击者可暴力遍历相邻时间戳下载敏感报表。 - 应对:上传文件重命名为
uniqid('', true)+random_bytes(8);归档路径加入哈希或 UUID,禁用纯时间戳可预测路径。
秒杀/抢购类接口的请求时效判定
常见于大促系统,用 microtime(true) 计算请求耗时或限制“提交窗口”。若仅校验客户端传入的 timestamp 参数(如微信 JS-SDK 签名中的 timestamp),而未结合服务端接收时刻做差值判断(如 abs($server_time - $client_ts) > 300),易受重放攻击。
- 关键点:必须记录请求到达服务端的精确时间(
$_SERVER['REQUEST_TIME_FLOAT']),并与客户端时间做双向容错校验,而非单向信任。
这些场景不是 PHP 7.3 特有,但在该版本中因 DateTime 类改进、date_default_timezone_set() 默认行为变化(如未显式设置时区可能回退到 UTC),反而放大了时区混淆导致的时间逻辑偏差——比如上海用户看到的“23:59”在服务端解析成 00:00 UTC,造成提前失效。
不复杂但容易忽略
立即学习“PHP免费学习笔记(深入)”;



















