悟道子
2022-06-21 16:44:59
服务器时间与数据库时间差导致逻辑上的漏洞
1、背景:
表结构如下表,逻辑上用户存在以下几种情况:
(1)、不参加任何活动,数据库中没有记录
(2)、只能参加一种活动,即活动一、活动二、活动三有效的记录只能存在1条
需求:根据记录判断当前用户属于何种身份,如果是活动三,返回活动倒计时的毫秒值。
CREATE TABLE `activity_record` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', `type` tinyint(2) DEFAULT NULL COMMENT '1-活动一 2-活动二 3-活动三', `uid` int(11) DEFAULT NULL COMMENT '用户id', `createTime` datetime DEFAULT NULL COMMENT '创建时间', `startTime` datetime DEFAULT NULL COMMENT '起始时间', `endTime` datetime DEFAULT NULL COMMENT '结束时间', `activityId` int(11) DEFAULT NULL COMMENT '活动id', `isvalid` tinyint(1) DEFAULT '1' COMMENT '是否生效 1-生效 0-失效', `expirationTime` datetime DEFAULT NULL COMMENT '失效时间', `clientType` int(2) DEFAULT NULL COMMENT '客户端类型' PRIMARY KEY (`id`), KEY `idx_uid` (`uid`) USING BTREE, KEY `idx_startTime` (`statTime`) USING BTREE, KEY `idx_endTime` (`endTime`) USING BTREE, KEY `idx_type` (`type`) USING BTREE, KEY `idx_activityId` (`activityId`) USING BTREE, KEY `idx_isvalid` (`isvalid`) USING BTREE, KEY `idx_createTime` (`createTime`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2、有漏洞的逻辑:
(1)、查询判断用户身份,并查询出有效记录最后的结束时间
select type,endTime from activity_record where startTime <= now() and endTime >now() limit 1 ;
(2)、如果是活动三(有记录,type=3)
Integer countDownTime = (validEndTime.getTime() - System.currentTimeMillis()) > 0?(validEndTime.getTime() - System.currentTimeMillis()):0;
结果发现
validEndTime.getTime() - System.currentTimeMillis() < 0,countDownTime=0,与活动三的身份相悖
原因是validEndTime.getTime() 是数据库记录的活动结束时间毫秒值,System.currentTimeMillis()是服务器当前的毫秒值,并不等于数据的当前时间,System.currentTimeMillis()与数据库的now()存在一定的时间差,可能存在System.currentTimeMillis() < now(),且代码的执行也有一定的时间。此种情况出现在活动即将结束的较短的时间内。
3、调整方案:
(1)、第一种,在2的基础上,以服务器时间为标杆,countDownTime=0逻辑上判定为活动过期,当前未参加任何活动,countDownTime > 0 && type=3,输出倒计时。
(2)、有二种,直接select数据库的记录算差值,type=3,countDownTime即为当前时间的倒计时(最优方案)
select type,TIMESTAMPDIFF(MICROSECOND,NOW(),endTime) as countDownTime from activity_record where startTime <= now() and endTime > now() limit 1;
评论

dapeng0011 LV15
2024年6月6日
stedian LV4
2023年12月20日
悟道子 LV16
2023年7月19日
小骆驼 LV3
2023年2月28日
itiswm
2023年2月27日
暂无贡献等级
欠踹de背影 LV25
2023年2月8日
wsh564494062 LV8
2023年1月28日
lonesafe LV11
2022年12月22日
ssk123
2022年12月15日
暂无贡献等级
八九不如意十 LV2
2022年11月25日