Ответ
При тестировании веб-приложений важно понимать, где клиентское приложение хранит JWT (JSON Web Token), так как это напрямую влияет на векторы атак. Основные места хранения:
1. В памяти (In-Memory / JavaScript переменные)
- Как: Токен хранится в переменной JavaScript (например, в состоянии SPA-фреймворка типа React/Vue).
- Безопасность: Высокая. Токен очищается при закрытии вкладки. Уязвим к XSS, но атакующий должен внедрить и выполнить вредоносный JS в контексте страницы.
- Тестирование: Проверяем, что токен не попадает в менее безопасные хранилища (LocalStorage) и очищается после логаута.
2. В сессионном хранилище (sessionStorage)
- Как:
sessionStorage.setItem('access_token', token) - Безопасность: Средняя. Токен сохраняется между перезагрузками страницы, но очищается при закрытии вкладки. Уязвим к XSS — если есть уязвимость, скрипт может прочитать токен из sessionStorage.
3. В локальном хранилище (localStorage)
- Как:
localStorage.setItem('access_token', token) - Безопасность: Низкая. Токен сохраняется навсегда, пока его явно не удалят. Крайне уязвим к XSS. Не рекомендуется для хранения токенов доступа (access token).
4. В защищенных куках (HttpOnly, Secure, SameSite Cookies)
- Как: Сервер устанавливает cookie с флагами
HttpOnly,Secure,SameSite=Strict. - Безопасность: Высокая против XSS (токен недоступен через JavaScript). Требует защиты от CSRF (с помощью того же флага
SameSiteили CSRF-токенов).
Современная и безопасная практика, которую я проверяю:
- Короткоживущий Access Token хранится в памяти JavaScript.
- Долгоживущий Refresh Token хранится в
HttpOnly, Secure, SameSite=Strictcookie. Он используется для получения нового access token'а, не участвуя в каждом запросе к API, что минимизирует риски.