fengzf的gravatar头像
fengzf 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;

 


打赏

已有1人打赏

最代码官方的gravatar头像
最近浏览
八九不如意十  LV2 11月25日
best2018  LV44 11月18日
li837437513  LV14 11月17日
dzhyshop 10月26日
暂无贡献等级
weixiao  LV6 10月23日
王雅坤  LV3 10月21日
ssy552  LV10 10月13日
yinzhilei 10月11日
暂无贡献等级
hunan27  LV11 10月10日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友