Розробка програмного забезпечення

Атаки на синхронізацію в PHP: Практичний приклад - чому `hash_equals()` має значення

Хочете побачити реальний приклад атаки на токени API у Wordpress/Laravel/PHP? Ми розглянемо його тут, включно з порадами та найкращими практичними заходами проти атак на синхронізацію.

Багато розробників покладаються на просте порівняння з використанням === або == при перевірці ключів API, токенів або інших секретних рядків. На перший погляд, це виглядає розумно - але є підступ: різниця в часі при порівнянні може бути використана зловмисниками.

У цій статті описано реалістичний приклад того, як концептуально працює атака на синхронізацію.

Реальний сценарій (спрощений приклад)

Уявіть, що внутрішній мікросервіс приймає запити з токеном параметра запиту і порівнює його з токеном API GitHub, що зберігається в середовищі.

Небезпечний код (спрощений):

// insecure.php (спрощений приклад)$expected = getenv('GITHUB_API_TOKEN');// наприклад, 'V1cHt2S67DADJIm9sX9yzCc272EkSC'$provided = $_GET['token'] ?? '';if ($provided === $expected) { // надаємо доступ} PHP  

Я поясню, чому це проблематично, в наступному розділі.

Як працює атака на час?

Якщо реалізація порівняння токенів порівнює посимвольно і переривається відразу при першій помилці, то запит з правильним першим символом в середньому виконується трохи довше.

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

Зловмисник користується цим, тестуючи всі можливі символи для кожної позиції, дуже часто вимірюючи час відгуку і статистично аналізуючи його. Символ з найбільшим середнім/пропорційно довшим часом, ймовірно, є правильним. Таким чином, токен реконструюється крок за кроком.

Чому hash_equals() є правильним вибором

PHP надає функцію порівняння рядків з постійним часом за допомогою hash_equals(). Це гарантує, що час виконання порівняння не залежить від спільних префіксів - поки обидва рядки мають однакову довжину.

Безпечна альтернатива (для Laravel, PHP, Wordpress):

// secure.php$expected = getenv('GITHUB_API_TOKEN'); $provided = $_GET['token'] ?? '';if (hash_equals($expected, $provided)) { // Надаємо доступ} PHP  

Примітка: hash_equals() є "незалежною від часу", тільки якщо довжини рівні. Рекомендується проектувати токени таким чином, щоб довжина була постійною (наприклад, HMAC, UUID фіксованої довжини або випадкові Base64-рядки фіксованої довжини).

Чи знаєте ви? Тільки UUID-V4 генерується повністю випадковим чином і тому часто використовується для токенів безпеки. Оскільки він не містить інформації, пов'язаної з часом або пристроєм, він пропонує високий рівень непередбачуваності і, таким чином, захищає від атак, заснованих на шаблонах або прогнозах. Саме тому UUID-V4 є найкращим вибором, коли мова йде про безпечні ідентифікатори, які важко вгадати.

Додаткові заходи захисту - більше, ніж просто hash_equals()

  1. Постійна довжина токена
    Використовуйте токени з фіксованою довжиною, наприклад, UUID-V4. Якщо зловмисник вгадає довжину, це буде менш корисно, оскільки самі символи захищені.
  2. Обмеження швидкості
    Обмежте кількість запитів на IP-адресу або на акаунт. Атаки з визначенням часу вимагають багато вимірювань; обмеження швидкості значно збільшує зусилля і витрати зловмисника.
  3. Логування та моніторинг
    Розпізнавайте незвичайні патерни (багато спроб введення токенів, систематична зміна певних параметрів) і реагуйте автоматично.
  4. Сіль / HMAC / Підписи
    Використовуйте підписані токени (HMAC з секретним ключем) або токени OAuth замість відкритого порівняння необроблених статичних ключів.
  5. TLS/HTTPS
    Шифрування захищає канали зв'язку - хоча воно і не запобігає атакам на внутрішні компоненти сервера, але є базовою вимогою.
  6. Ротація токенів
    Короткий термін служби токенів зменшує вигоду від скомпрометованого токена.

Висновок

Атаки на синхронізацію не є суто теоретичною проблемою - вони були досліджені на практиці і можуть мати серйозні наслідки, особливо для загальнодоступних кінцевих точок. Хороша новина: для розробників PHP/Laravel/Wordpress перша контрзахід дуже проста:

  • Замініть прямі порівняння чутливих рядків на hash_equals().
  • Забезпечте постійну довжину токенів, обмеження швидкості, ведення журналів і безпечне управління токенами.
Про автора
Засновник і генеральний директор Langmeier Software
Я не хочу нічого ускладнювати. Я не хочу розробляти ідеальне програмне забезпечення для бізнесу. Я не хочу бути включеним до списку найкращих технологій. Тому що це не те, для чого потрібні бізнес-додатки. Вони для того, щоб забезпечити надійний захист ваших даних. І це означає, що все має працювати безперебійно, поки ви зберігаєте повний контроль і можете зосередитися на розвитку вашого бізнесу. Простота та надійність - це мої керівні принципи, які надихають мене щодня.
 
Подивіться далі:
PHP, Інформування про безпеку, кібербезпека
Відповідні статті