Розробка програмного забезпечення
Атаки на синхронізацію в PHP: Практичний приклад - чому `hash_equals()` має значення
Хочете побачити реальний приклад атаки на токени API у Wordpress/Laravel/PHP? Ми розглянемо його тут, включно з порадами та найкращими практичними заходами проти атак на синхронізацію.
Багато розробників покладаються на просте порівняння з використанням === або == при перевірці ключів API, токенів або інших секретних рядків. На перший погляд, це виглядає розумно - але є підступ: різниця в часі при порівнянні може бути використана зловмисниками.
У цій статті описано реалістичний приклад того, як концептуально працює атака на синхронізацію.
Реальний сценарій (спрощений приклад)
Уявіть, що внутрішній мікросервіс приймає запити з токеном параметра запиту і порівнює його з токеном API GitHub, що зберігається в середовищі.
Небезпечний код (спрощений):
$expected = getenv('GITHUB_API_TOKEN');$provided = $_GET['token'] ?? '';if ($provided === $expected) { } PHP
Я поясню, чому це проблематично, в наступному розділі.
Як працює атака на час?
Якщо реалізація порівняння токенів порівнює посимвольно і переривається відразу при першій помилці, то запит з правильним першим символом в середньому виконується трохи довше.
Отже, правильний перший символ в середньому призводить до трохи більшого часу обробки, ніж неправильний перший символ. Те ж саме стосується другого символу і так далі.
Зловмисник користується цим, тестуючи всі можливі символи для кожної позиції, дуже часто вимірюючи час відгуку і статистично аналізуючи його. Символ з найбільшим середнім/пропорційно довшим часом, ймовірно, є правильним. Таким чином, токен реконструюється крок за кроком.
Чому hash_equals() є правильним вибором
PHP надає функцію порівняння рядків з постійним часом за допомогою hash_equals(). Це гарантує, що час виконання порівняння не залежить від спільних префіксів - поки обидва рядки мають однакову довжину.
Безпечна альтернатива (для Laravel, PHP, Wordpress):
$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()
- Постійна довжина токена
Використовуйте токени з фіксованою довжиною, наприклад, UUID-V4. Якщо зловмисник вгадає довжину, це буде менш корисно, оскільки самі символи захищені.
- Обмеження швидкості
Обмежте кількість запитів на IP-адресу або на акаунт. Атаки з визначенням часу вимагають багато вимірювань; обмеження швидкості значно збільшує зусилля і витрати зловмисника.
- Логування та моніторинг
Розпізнавайте незвичайні патерни (багато спроб введення токенів, систематична зміна певних параметрів) і реагуйте автоматично.
- Сіль / HMAC / Підписи
Використовуйте підписані токени (HMAC з секретним ключем) або токени OAuth замість відкритого порівняння необроблених статичних ключів.
- TLS/HTTPS
Шифрування захищає канали зв'язку - хоча воно і не запобігає атакам на внутрішні компоненти сервера, але є базовою вимогою.
- Ротація токенів
Короткий термін служби токенів зменшує вигоду від скомпрометованого токена.
Висновок
Атаки на синхронізацію не є суто теоретичною проблемою - вони були досліджені на практиці і можуть мати серйозні наслідки, особливо для загальнодоступних кінцевих точок. Хороша новина: для розробників PHP/Laravel/Wordpress перша контрзахід дуже проста:
- Замініть прямі порівняння чутливих рядків на
hash_equals().
- Забезпечте постійну довжину токенів, обмеження швидкості, ведення журналів і безпечне управління токенами.