微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

修复定时攻击

如何解决修复定时攻击

我使用此代码登录用户。密码用 bcrypt 加密,每个用户SALT_ROUNDS 都是一样的

const user = await User.findOne({email: args.email});
if (!user || !await user.comparePassword(args.password)) throw new Error("User or Password is not correct");

(comparePassword 是一个猫鼬函数

UserSchema.methods.comparePassword = async function (candidatePassword) {
    return await bcrypt.compare(candidatePassword,this.password);
};

如您所见,由于短路,if-check 可能需要不同的时间来执行 - 这对客户来说是可以衡量的。

这意味着,客户可以查明某封电子邮件是否使用了我们的服务——这是一次轻微的数据泄露。

我需要这样的脚本:

const err = new Error("User or Password is not correct.")
if (!user) {
  await "wait as long as a password comparison would usually take"
  throw err
} else if (!await user.comparePassword(args.password)) {
  throw err
}

但不知道如何实现它。

一个想法是创建一个虚拟用户来在 if comparePassword 上创建 !user,但我不确定它的优点/缺点,或者是否有更好的解决方案。>

编辑:我将所有这些都包含在一个 setTimeout 函数中如何?无论如何都需要 1 秒(或 500 毫秒之类的)。

解决方法

我想出了这个解决方案:

const user = await User.findOne({email: args.email});

const start = performance.now()
const errorToThrow = (!user || !await user.comparePassword(args.password))
const timeElapsed = performance.now() - start

//console.log(`time elapsed: ${timeElapsed}`)
//wait constant time to protect against timing attacks
// OPTIMIZE still able to go for timing attack if `comparePassword` takes >1000ms
await new Promise((resolve) => {
    setTimeout(resolve,1000 - timeElapsed);
});
//console.log(`Constant wait time: ${performance.now() - start}`)

if (errorToThrow) throw new Error("User or Password is not correct.")

//generate token
return jwt.sign({
        _id: user._id,username: user.name,role: user.role
    },process.env.JWT_SECRET,{
        expiresIn: "24h"
    });

并且衡量性能表明这是有效的

#successful login
time elapsed: 111.46860000118613
Constant wait time: 1008.9731000009924
time elapsed: 77.95830000005662
Constant wait time: 1011.4061999991536
time elapsed: 77.98919999971986
Constant wait time: 1001.5624000001699
time elapsed: 73.09439999982715
Constant wait time: 1000.9662999995053

#user doesnt exist
time elapsed: 0.002399999648332596
Constant wait time: 1015.8186999987811
time elapsed: 0.002199999988079071
Constant wait time: 1006.2013000007719
time elapsed: 0.0023000016808509827
Constant wait time: 1006.3976000007242
time elapsed: 0.0037999991327524185
Constant wait time: 1003.9857000000775

#password incorrect
time elapsed: 74.4993999991566
Constant wait time: 1009.0491999983788
time elapsed: 73.85539999976754
Constant wait time: 1012.3958000000566
time elapsed: 75.48650000058115
Constant wait time: 1014.1987999994308
time elapsed: 71.53899999894202
Constant wait time: 1007.4519999995828
time elapsed: 74.53729999996722
Constant wait time: 1001.8896000012755

所以除非服务器需要 10 倍的时间来响应此工作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。