До всіх новин
Щоденник розробників

Шість цифр: як було закрито вхід від перебору

Звіт про безпеку показав, що чотиризначний код підбирався за кілька діб. Тепер код шестизначний, а ліміт спроб не оновлюється разом із новим кодом.
Картка входу в гру на тлі розмитого села

Один мій товариш надіслав звіт про безпеку Ізоманії, який, своєю чергою, підготував його ШІ-агент — дванадцять пунктів. Девʼять із них уже були закриті в коді, один виявився хибною тривогою, а перший був серйознішим, ніж його оцінили в самому звіті.

Чому чотири цифри не є захистом (код підтвердження авторизації)

Код підтвердження з пошти мав чотири цифри і пʼять спроб введення. Це виглядає прийнятним, поки не порахувати: новий код коштує зловмиснику одного запиту, і разом із ним оновлюється ліміт спроб. Пʼять надсилань за чверть години по пʼять спроб кожне дають 2 400 варіантів на добу при просторі в 10 000 комбінацій. Це приблизно 21 відсоток імовірності захопити конкретний обліковий запис за добу і менш ніж три доби в медіані.

Капча тут не допомагає, бо розвʼязані завдання продаються приблизно по долару за тисячу. Не допомагає і блокування: щоб чотиризначний код став надійним, довелося б блокувати гравця вже за дві помилки, тобто карати звичайну людину за одруківку.

Шість цифр і ліміт, який не оновлюється

Код тепер шестизначний, тобто мільйон варіантів замість десяти тисяч. Під ним працюють два окремі ліміти помилок.

Лист із шестизначним кодом підтвердження

Перший рахується на адресу пошти сумарно по всіх кодах у межах часового вікна, тому запит нового коду вже нічого не дає. Другий рахується на IP-адресу, бо один компʼютер, який перебирає багато різних адрес, першого ліміту не торкнеться.

Обидва ліміти витрачаються тільки на помилки і перевіряються до порівняння коду, тому при вичерпаному ліміті відхиляється навіть правильний код. Це не надмірність, а точність: виграшна спроба зловмисника теж є правильним кодом.

Додаткові обмеження

  • Перевірка походження запиту при встановленні зʼєднання, тому сторонній сайт не може відкрити зʼєднання від імені гравця.
  • Обмеження кількості повідомлень на одне зʼєднання: 240 на секунду при реальному навантаженні близько 80. Частина повідомлень розсилається всім гравцям, тому потік має коштувати простої відмови, а не розбору і розсилки.
  • Камера і мікрофон обмежені політикою дозволів на рівні сторінки, тому вбудовані сторонні фрейми до них не дістануться.

Помилка, якої не знайшли тести

Найпоказовішу помилку цієї історії знайшли не тести і не аналіз коду. Вставлений з листа шестизначний код заповнював лише чотири поля, бо в коді залишилося старе обрізання до чотирьох символів. Тест, який мав це виявити, шукав у файлі правильні ознаки і знаходив їх, хоча поруч працювала неправильна умова.

Тепер логіка вставки винесена в спільний модуль і перевіряється виконанням, а не читанням вихідного коду.

Підсумкова вичитка змін знайшла ще близько десятка дрібніших проблем: від шостого поля введення, яке не вміщалося на екрані шириною 320 пікселів, до повідомлення про помилку, яке радило запросити новий код саме тоді, коли новий код уже не міг допомогти.

Разом із цим оновленням у проєкті працює 409 автоматичних перевірок, і кожне правило з цієї статті серед них.

Читайте також

Оновлення

Машини у відкритому світі, системні зони і оптимізація рушія

Відкритий світ отримав машини, а область появи гравця перестала бути захардкоженою точкою і стала пензлем-зоною в редакторі мапи. Разом із цим світ навчився бути великим: увесь…
Читати оновлення