open atlas
↑ К треку
Безопасность SEC · 05 · 09

Хеширование паролей: разбор кода

Читай реальные auth-сниппеты — параметры Argon2id, наивное хранение SHA-256, timing-unsafe сравнение и отсутствующий rehash-on-login — и выбирай фикс, который сделает senior первым.

SEC Senior ◷ 14 min
Уровень
ОсновыJuniorMiddleSenior

Баги в паролях прячутся в коде, который выглядит нормально и проходит happy-path тест. Прочитай каждый сниппет, найди дефект, который вскрыла бы утечка или нагрузочный тест, и выбери фикс, за которым senior тянется первым.

Цель

Отработай цикл ревью: прочитать auth-путь, найти криптографический или тайминговый дефект и выбрать максимально рычажную правку до отправки в production.

Сниппет 1 — наивное хранение

import { createHash } from "node:crypto";

function storePassword(user, password) {
  const hash = createHash("sha256").update(password).digest("hex");
  db.users.update(user.id, { passwordHash: hash });
}
Викторина

Что здесь не так и каков один максимально рычажный фикс?

Сниппет 2 — параметры Argon2id

import argon2 from "argon2";

async function hashPassword(password) {
  return argon2.hash(password, {
    type: argon2.argon2id,
    memoryCost: 512,   // KiB
    timeCost: 1,
    parallelism: 1,
  });
}
Викторина

Выбор алгоритма верный. Что не так с настройкой?

Сниппет 3 — сравнение

function verifyResetToken(provided, stored) {
  // оба — hex-кодированные HMAC-дайджесты
  if (provided === stored) {
    return true;
  }
  return false;
}
Викторина

Здесь два секретных дайджеста сравниваются через ===. Почему это проблема и каков фикс?

Сниппет 4 — вход без миграции

async function login(email, password) {
  const user = await db.users.findByEmail(email);
  if (!user) return null;
  const ok = await argon2.verify(user.passwordHash, password);
  if (!ok) return null;
  return issueSession(user);
}
Викторина

Verify верный и constant-time. Что этот вход упускает, что важно по мере старения параметров?

Итог

Это дефекты, которые находишь в реальных auth-ревью: быстрый хеш без salt должен стать медленным, memory-hard KDF; Argon2id с заниженным memory cost выбрасывает свойство, душащее GPU, поэтому соблюдай OWASP m=19 MiB/t=2/p=1; сравнения секретов должны быть constant-time (crypto.timingSafeEqual или собственный verify KDF), а не ===; а корректный verify всё равно нуждается в rehash-on-login через needsRehash, чтобы держать work factor актуальным без принудительных сбросов. Диагностируй алгоритм, параметры, тайминг и миграцию — именно в этом порядке. Теперь, открывая auth-PR, эти четыре вопроса срабатывают автоматически — и ты ловишь проблему дня утечки до того, как она уходит в продакшн.

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.