NodeClub代码的一个安全风险!Nodejs版

NodeClub代码的一个安全风险!Nodejs版

我看了一下NodeClub的源码,关于登录认证这部分我觉得是很有风险的。NodeClub作为一个开源程序,估计会有人图省事不会去修改session_secret

先看看生成认证Session代码:

function gen_session(user, res) {
  var auth_token = encrypt(user._id + '\t' + user.name + '\t' + user.pass + '\t' + user.email, config.session_secret);
  res.cookie(config.auth_cookie_name, auth_token, {path: '/', maxAge: 1000 * 60 * 60 * 24 * 30}); //cookie 有效期30天
}

这个代码有几个问题:

  • 只要用户没修改密码和session secret,每次加密后结果其实是一样的,也就是用户每次登录后Cookie的值都是一样的,它是不会过期的,如果泄漏,那么就会被伪造,用户除了修改密码毫无办法。
  • 加密使用的对称加密,如果session_secret泄密,那么Cookie的值会被解密。如果只是解密倒还是小事,关键会把用户的密码user.pass也看到,这很要命!虽然pass是md5之后的,但是md5并没有加上salt,所以有可能是会暴露一些信息的,因为只要密码一样,那么md5后的结果必然一样的。
  • 如果session_secret泄密,那么可以加密结果直接伪造身份

建议:

  • 登录后的Cookie加密时增加时间戳,保证每次登录后Cookie是不一样的,并且校验时根据时间戳判断过期
  • user.pass不要放在加密内容里面
  • 提醒用户session_secret不修改导致的严重后果(最好是能安装时随机生成一个)

3 回复

NodeClub代码的一个安全风险!Nodejs版

我看了一下NodeClub的源码,关于登录认证这部分我觉得是很有风险的。NodeClub作为一个开源程序,估计会有人图省事不会去修改session_secret

先看看生成认证Session代码:

function gen_session(user, res) {
  var auth_token = encrypt(user._id + '\t' + user.name + '\t' + user.pass + '\t' + user.email, config.session_secret);
  res.cookie(config.auth_cookie_name, auth_token, {path: '/', maxAge: 1000 * 60 * 60 * 24 * 30}); // cookie 有效期30天
}

这段代码存在几个潜在的安全问题:

  1. Cookie值固定不变

    • 只要用户没有修改密码和session_secret,每次加密后的结果都是相同的,这意味着Cookie的值不会改变。如果Cookie泄露,攻击者可以使用相同的Cookie进行登录,而用户无法通过修改密码来撤销这个Cookie。
  2. 使用对称加密

    • 如果session_secret泄露,攻击者可以解密Cookie中的信息。更糟糕的是,用户密码(user.pass)也会被暴露出来。尽管密码已经经过MD5哈希处理,但如果多个用户使用相同的密码,攻击者仍然可以通过比较哈希值来识别这些用户。
  3. 容易被伪造身份

    • 如果session_secret泄露,攻击者可以直接构造合法的Cookie进行身份伪造。

建议改进:

为了提高安全性,我们可以对上述代码进行以下改进:

  1. 增加时间戳以确保每次登录后Cookie不同

    • 在生成Cookie时,加入当前时间戳,这样每次登录后Cookie都会不同。同时,在验证Cookie时,根据时间戳判断其是否过期。
    function gen_session(user, res) {
      var timestamp = Date.now();
      var auth_token = encrypt(user._id + '\t' + user.name + '\t' + timestamp, config.session_secret);
      res.cookie(config.auth_cookie_name, auth_token, {path: '/', maxAge: 1000 * 60 * 60 * 24 * 30}); // cookie 有效期30天
    }
    
  2. 移除用户密码

    • 不要在加密内容中包含用户密码,只保留必要的信息,如用户ID和用户名。
    function gen_session(user, res) {
      var timestamp = Date.now();
      var auth_token = encrypt(user._id + '\t' + user.name + '\t' + timestamp, config.session_secret);
      res.cookie(config.auth_cookie_name, auth_token, {path: '/', maxAge: 1000 * 60 * 60 * 24 * 30}); // cookie 有效期30天
    }
    
  3. 提醒用户修改默认的session_secret

    • 在安装过程中随机生成一个session_secret,并提醒用户不要使用默认值。如果用户继续使用默认值,可能会面临严重的安全风险。

通过以上改进,可以显著提升NodeClub的安全性,减少潜在的风险。


…这个咱们程序员不会连这个常识都没吧…

根据你描述的问题,NodeClub的登录认证机制确实存在一定的安全隐患。主要问题是session的加密方式容易被破解或伪造,尤其是在session_secret未被修改的情况下。

改进建议

  1. 使用不同的加密内容:避免在加密内容中包含敏感信息,如user.pass
  2. 添加时间戳:确保每次登录后的Cookie值不同,并且可以根据时间戳来判断是否过期。
  3. 使用更强的加密算法:推荐使用更安全的加密算法和密钥管理方法。

示例改进代码

const crypto = require('crypto');
const moment = require('moment');

function gen_session(user, res, sessionSecret) {
    const timestamp = moment().unix();  // 获取当前时间戳
    const dataToEncrypt = `${user._id}\t${user.name}\t${timestamp}`;
    const auth_token = encrypt(dataToEncrypt, sessionSecret);

    res.cookie(config.auth_cookie_name, auth_token, {
        path: '/',
        maxAge: 1000 * 60 * 60 * 24 * 30, // Cookie有效期30天
        httpOnly: true, // 增加安全性,禁止JavaScript访问cookie
        secure: true   // 如果使用HTTPS,则应设置为true
    });
}

function encrypt(data, secret) {
    const cipher = crypto.createCipher('aes-256-cbc', secret);
    let encrypted = cipher.update(data, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    return encrypted;
}

function decrypt(encryptedData, secret) {
    const decipher = crypto.createDecipher('aes-256-cbc', secret);
    let decrypted = decipher.update(encryptedData, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
}

// 使用示例
gen_session({ _id: '123', name: 'testuser' }, res, 'your-session-secret');

解释

  1. 使用时间戳:每次登录时,都会生成一个新的时间戳,这样即使session_secret没有改变,每次生成的Cookie值也会不同。
  2. 加密内容:只加密必要的信息,例如用户ID和用户名,而不是用户的密码。
  3. 增强安全性:在设置Cookie时增加httpOnlysecure标志,提高安全性。

通过这些改进,可以显著提升NodeClub的安全性,减少因Cookie泄露而带来的潜在风险。

回到顶部