PHP PHP  ·  30 вопросов  ·  ~85 мин  ·  ⏱ Таймер 25:00  ·  Сложный  · 

Пароли и аутентификация

Задания проходят весь путь от создания хеша до смены пароля и отзыва активных сеансов. Нужно отличать пароль от токена, безопасно сравнивать значения и проектировать восстановление доступа без раскрытия учётных записей.

Отвечено: 0 из 30
⏱ --:--
0%
💡 Инструкция: Выберите один ответ из пяти. Для каждого секрета определите срок жизни, способ хранения и последствия утечки. Таймер — 85 минут.
Вопрос 1 из 30
Как получить значение для хранения, которое использует текущий рекомендуемый алгоритм PHP и затем проверяется через password_verify()?
PHP
$password = $_POST['password'] ?? '';
Вопрос 2 из 30
Нужно ли хранить соль в отдельном столбце?
PHP
$first = password_hash('same password', PASSWORD_DEFAULT);
$second = password_hash('same password', PASSWORD_DEFAULT);
var_dump($first !== $second);
Вопрос 3 из 30
Почему столбец хеша делают с запасом, например varchar(255)?
SQLSQL — схема хранения
CREATE TABLE users (
  id BIGINT PRIMARY KEY,
  password_hash VARCHAR(255) NOT NULL
);
Вопрос 4 из 30
Что произойдёт для одинакового пароля при двух вызовах?
PHP
$a=password_hash('secret',PASSWORD_DEFAULT);
$b=password_hash('secret',PASSWORD_DEFAULT);
var_dump($a!==$b,password_verify('secret',$a),password_verify('secret',$b));
Вопрос 5 из 30
Почему быстрый SHA-256 без KDF слаб для паролей?
Вопрос 6 из 30
Как сравнивать введённый пароль с сохранённым хешем?
PHP
if (!password_verify($password, $user->passwordHash)) {
    throw new AuthenticationFailed();
}
Вопрос 7 из 30
Для чего password_needs_rehash?
PHP
if (password_verify($password, $hash)
    && password_needs_rehash($hash, PASSWORD_DEFAULT)) {
    $users->updatePasswordHash($userId, password_hash($password, PASSWORD_DEFAULT));
}
Вопрос 8 из 30
Почему ответ «пользователь не найден» нежелателен на форме входа?
PHP
$user = $users->findByEmail($email);
$valid = $user !== null && password_verify($password, $user->passwordHash);
if (!$valid) {
    throw new AuthenticationFailed('Неверные учётные данные');
}
Вопрос 9 из 30
Что делать для неизвестного email, чтобы не было сильной временной разницы?
Вопрос 10 из 30
Какой порядок корректен?
PHP
if($user && password_verify($password,$user->hash)){
 session_regenerate_id(true);
 $_SESSION['uid']=$user->id;
 if(password_needs_rehash($user->hash,PASSWORD_DEFAULT)) $repo->rehash($user->id,password_hash($password,PASSWORD_DEFAULT));
}
Вопрос 11 из 30
Каким должен быть токен сброса?
PHP
$token = bin2hex(random_bytes(32));
$expiresAt = $clock->now()->modify('+30 minutes');
Вопрос 12 из 30
Что хранить в базе?
PHP
$plainToken = bin2hex(random_bytes(32));
$storedHash = hash('sha256', $plainToken);
$resets->create($userId, $storedHash, $expiresAt);
Вопрос 13 из 30
Как обеспечить одноразовость при двух одновременных запросах?
PHP
$stmt = $pdo->prepare(
    'UPDATE password_resets SET used_at = NOW() '
    . 'WHERE token_hash = :hash AND used_at IS NULL AND expires_at > NOW()'
);
$stmt->execute(['hash' => $tokenHash]);
if ($stmt->rowCount() !== 1) throw new InvalidToken();
Вопрос 14 из 30
Почему токен не стоит передавать сторонним ресурсам через Referer?
Вопрос 15 из 30
Что сделать после успешного сброса?
Вопрос 16 из 30
Почему session_regenerate_id(true) нужна после входа?
PHP
session_start();
if ($auth->verify($email, $password)) {
    session_regenerate_id(true);
    $_SESSION['user_id'] = $auth->userId();
}
Вопрос 17 из 30
Как реализовать «выйти со всех устройств»?
PHP
$users->incrementAuthVersion($userId);
$sessions->deleteAllForUser($userId);
Вопрос 18 из 30
Зачем повторно спрашивать пароль/MFA перед сменой email?
PHP
if (!$reauth->verifiedRecently($session)) {
    return new RedirectResponse('/confirm-password');
}
$emailChanger->change($userId, $newEmail);
Вопрос 19 из 30
Что хранить в сессии вместо полного объекта User?
Вопрос 20 из 30
Как сочетать абсолютный и неактивный срок?
Вопрос 21 из 30
Какие пароли нужны в тесте?
PHP
$cases = [
    'correct' => ['correct horse', true],
    'wrong' => ['wrong', false],
    'empty' => ['', false],
    'unicode' => ['пароль🔐', true],
    'long' => [str_repeat('a', 200), false],
];
Вопрос 22 из 30
Что проверять при rehash?
PHP
$oldHash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 10]);
assert(password_verify($password, $oldHash));
assert(password_needs_rehash($oldHash, PASSWORD_BCRYPT, ['cost' => 12]));
$newHash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
assert(password_verify($password, $newHash));
Вопрос 23 из 30
Что нельзя журналировать?
Вопрос 24 из 30
Как тестировать rate limit без ожидания реальных минут?
Вопрос 25 из 30
Какая ошибка важна при неизвестном пользователе?
Вопрос 26 из 30
Что даёт MFA?
PHP
$passwordOk = password_verify($password, $user->passwordHash);
$totpOk = $totp->verify($user->totpSecret, $code);
if (!$passwordOk || !$totpOk) throw new AuthenticationFailed();
Вопрос 27 из 30
Как ограничивать перебор без вечной блокировки жертвы?
PHP
$key = hash('sha256', mb_strtolower($email) . '|' . $sourceNetwork);
if (!$limiter->consume($key, $clock->now())) {
    throw new TooManyAttempts(retryAfter: $limiter->retryAfter($key));
}
Вопрос 28 из 30
База хешей утекла. Что делать?
Вопрос 29 из 30
Почему PASSWORD_DEFAULT нужно сочетать с password_needs_rehash?
Вопрос 30 из 30
Какое уведомление полезно после смены пароля?

Ответьте на все 30 вопросов, чтобы получить результат

🔗 Встроить тест на свой сайт (iframe) ▼

Скопируйте код и вставьте в любое место на вашем сайте:

Также доступна прямая ссылка на embed-страницу