Serverpod 升级密码哈希存储安全机制:应对彩虹表攻击的 Argon2Id 方案

本文详细介绍了 Serverpod 框架中一个中等级别的安全漏洞(CVE-2024-29886)。该漏洞涉及旧版本密码哈希算法易受彩虹表攻击的问题,并详细说明了官方在 1.2.6 版本中如何采用 OWASP 推荐的 Argon2Id 算法进行修复,以及如何迁移现有数据库中的旧哈希值。

CVE-2024-29886:Serverpod 改进存储密码哈希的安全性

漏洞详情

  • : serverpod_auth_server (Pub)
  • 受影响版本: < 1.2.6
  • 已修复版本: 1.2.6
  • 严重程度: 中等 (CVSS 评分 5.3)
  • 弱点: CWE-916 - 使用计算量不足的密码哈希

描述

Serverpod 现已使用 OWASP 推荐的 Argon2Id 密码哈希算法来存储电子邮件认证模块的密码哈希。

从 Serverpod 1.2.6 开始,所有创建账户或通过服务器进行身份验证的用户,其密码都将使用这种更安全的算法存储。开发者无需进行任何更改即可开始使用更安全的算法存储密码。

为什么我们要更改密码存储方式?

旧密码哈希算法被发现在数据库泄露时容易受到彩虹表攻击。强烈建议迁移您现有的密码哈希。

迁移现有密码哈希

电子邮件认证模块提供了一个辅助方法来迁移数据库中所有现有的遗留密码哈希。只需使用会话实例作为参数调用 Emails.migrateLegacyPasswordHashes(...) 即可迁移密码哈希。

该方法被实现为一个幂等操作,无论调用多少次,结果都是相同的。

我们建议要么实现一个可以远程调用的 Web 服务器路由,要么在启动服务器时调用此方法。

以下是实现 Web 服务器路由的示例代码。

Web 服务器路由代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import 'dart:io';

import 'package:serverpod/serverpod.dart';
import 'package:serverpod_auth_server/module.dart' as auth;

class MigratePasswordsRoute extends Route {
  @override
  Future<bool> handleCall(Session session, HttpRequest request) async {
    request.response.writeln(
      'Migrating legacy passwords, check the server logs for progress updates.',
    );
    _migratePasswords(session);
    return true;
  }
}

Future<void> _migratePasswords(Session session) async {
  session.log('Starting to migrate passwords.');

  var totalMigratedPasswords = 0;
  while (true) {
    try {
      var entriesMigrated = await auth.Emails.migrateLegacyPasswordHashes(
        session,
        // Process 100 database entries at a time
        batchSize: 100,
        // Stop after 500 entries have been migrated
        maxMigratedEntries: 500,
      );

      totalMigratedPasswords += entriesMigrated;
      session.log(
        'Migrated $entriesMigrated password entries, total $totalMigratedPasswords.',
      );

      if (entriesMigrated == 0) break;

      // Delay to avoid overloading the database
      await Future.delayed(Duration(seconds: 1));
    } catch (e) {
      session.log('Error migrating passwords: $e');
    }
  }

  session.log('Finished migrating passwords.');
}

我们如何迁移现有密码哈希

由于在不知道明文密码的情况下无法重新计算密码哈希,电子邮件认证模块中的方法将新算法应用于已存储的密码哈希。

当受影响的用户稍后进行身份验证时,他们的密码哈希将同时使用两种算法计算。如果认证通过,存储的密码哈希将更新为仅使用新算法,以便后续身份验证只需运行新算法。

影响

所有 1.2.6 之前版本的 serverpod_auth_server

补丁

升级到 1.2.6 版本可解决此问题。

参考

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计