GET /api/export?api_token=sk_live_9f8a...
Токен у рядку запиту «протікає» в місця, які ніхто не захищає як сховище секретів:
- журнали доступу вебсервера, балансувальника, CDN, проксі - URL записується повністю;
- історія браузера й закладки;
- заголовок
Referer- при переході з такої сторінки на інший сайт URL може піти туди; - системи моніторингу й аналітики (Sentry, APM), що записують URL запитів;
- кеш проксі - відповідь може закешуватися за URL з токеном;
- знімки екрана й повідомлення в чатах підтримки.
RFC 6750 прямо не рекомендує передавати bearer-токени в параметрах URL, крім випадків, коли інших варіантів немає.
Правильно - заголовок:
Authorization: Bearer sk_live_9f8a...
Якщо URL без токена неможливий (завантаження файлу за посиланням, WebSocket у браузері, вбудовування зображення) - короткоживучий одноразовий токен чи підписаний URL з терміном дії, прив'язаний до конкретного ресурсу:
URL::temporarySignedRoute('exports.download', now()->plus(minutes: 10), ['export' => $export]);
Що ще не повинно потрапляти в логи API:
- заголовки
Authorization,Cookie,X-Api-Key; - паролі, коди підтвердження, одноразові коди 2FA (типово - поля
password,token,codeу тілі); - номери карток, персональні документи, медичні дані;
- повні тіла відповідей із персональними даними.
Як це забезпечити:
- маскування в логах централізовано (процесор логів, фільтр полів у Sentry/Telescope), а не «не забути» в кожному місці;
- у Laravel -
$hiddenдля серіалізації моделей,#[\SensitiveParameter]для параметрів функцій (значення не з'явиться в стеку винятку), налаштуванняdontFlashдля полів, що не повертаються у форму після помилки; - токени з префіксом (
sk_live_...) - їх легше знайти й замаскувати сканерами секретів. Sanctum підтримує префікс черезtoken_prefix.
Якщо секрет усе ж потрапив у лог чи репозиторій - вважати його скомпрометованим і відкликати, а не лише видалити запис.