Лучшие практики создания приложений OAuth 2.0
Info
Рекомендации по безопасной разработке и настройке приложений OAuth 2.0 в GitVerse.
Безопасное хранение Client Secret
- никогда не храните Client Secret в клиентском коде (JavaScript в браузере, мобильные приложения). Secret должен быть доступен только на сервере;
- используйте переменные окружения для хранения секрета на сервере (
.env, секреты CI/CD); - не коммитьте Client Secret в репозитории. Добавьте файлы с секретами в
.gitignore; - регенерируйте Secret сразу, если обнаружили его утечку.
Danger
Если Client Secret скомпрометирован, злоумышник может выдавать токены от имени вашего приложения.
Всегда используйте PKCE
PKCE (Proof Key for Code Exchange, RFC 7636) защищает от перехвата authorization code при передаче от сервера авторизации к клиенту. Механизм привязывает запрос авторизации и обмен кода на токен к единому криптографическому идентификатору, что делает бесполезным перехваченный код без знания code_verifier.
Info
Полное описание и пошаговый алгоритм PKCE см. в разделе Что такое PKCE?.
- PKCE обязателен в GitVerse для всех типов клиентов (Публичных и Конфиденциальных) на GitVerse;
- всегда используйте метод
S256(SHA-256), а неplain; code_verifierдолжен состоять из случайных символовA-Z,a-z,0-9,-,.,_,~(длина 43–128 символов);- храните
code_verifierв безопасном хранилище клиента до обмена кода на токен.
code_challenge_method=S256Danger
Без PKCE злоумышленник, перехвативший код авторизации (например, через прокси или скомпрометированный Redirect URI), сможет обменять его на access token.
Запрашивайте минимально необходимые scope
- уважайте решение пользователя: если scope отклонены, приложение должно корректно обработать ошибку
access_denied; - проверяйте выданные scope на стороне сервера, чтобы не использовать права, которые не были подтверждены.
| Плохо | Хорошо |
|---|---|
scope=all | scope=read:user read:repository |
scope=write:repository write:issue | scope=read:repository (если достаточно чтения) |
Защита от CSRF
CSRF (Cross-Site Request Forgery) — атака, при которой злоумышленник заставляет аутентифицированного пользователя выполнить нежелательное действие на доверенном сайте без его ведома. В контексте OAuth 2.0 атака может привести к тому, что пользователь непреднамеренно авторизует злонамеренное приложение или выполнит несанкционированный callback.
Параметр state защищает от CSRF: сервер генерирует уникальное значение, привязанное к сессии пользователя, и проверяет его при возврате из авторизации. Если state не совпадает — запрос отвергается.
Info
Подробнее о CSRF-атаках и защите через параметр
stateсм. в разделе Что такое CSRF?.
Всегда используйте параметр state при запросе авторизации:
- Сгенерируйте криптографически случайную строку (минимум 32 байта).
- Передайте ее в
GET /authorize?state=.... - При callback проверьте, что возвращенный
stateточно совпадает с оригиналом.
Warning
Без проверки
stateприложение уязвимо для CSRF-атак.
Обработка истечения токенов
Access token живет 1 час. Приложение должно:
- Отслеживать ответы
401 Unauthorized. - При получении 401 использовать refresh_token для получения нового access_token.
- Повторить запрос с новым токеном.
- Если refresh_token истек (30 дней) — направить пользователя на повторную авторизацию.
Валидация Redirect URI
- точно сравнивайте
redirect_uriпри авторизации с зарегистрированным URI; - разрешайте только
https://для продакшн иhttp://localhost:*для разработки; - не используйте wildcard-URI в продакшн-окружении.
Loopback URI для локальной разработки
Для локальной разработки используйте loopback-адрес. Согласно RFC 8252, рекомендуется предпочитать числовой IP-адрес 127.0.0.1 вместо имени хоста localhost:
| Вариант | Статус |
|---|---|
http://127.0.0.1:PORT/callback | Рекомендуется (RFC 8252 §8.3) |
http://localhost:PORT/callback | Разрешен, но 127.0.0.1 предпочтительнее |
Оба варианта работают, однако 127.0.0.1 снижает риск атак через подмену DNS на уровне локальной машины.
Безопасная работа с токенами
- не логируйте access_token и refresh_token;
- не передавайте токены в URL (только в заголовке
Authorization: Bearer); - не кэшируйте refresh_token — при ротации старый токен становится недействительным;
- храните токены в защищенном хранилище (encrypted storage, secure cookie для браузерных приложений).
Мониторинг подключенных приложений
- регулярно проверяйте список подключенных приложений в Настройки → Приложения OAuth 2.0 → Подключенные приложения;
- отзывайте доступ к приложениям, которые больше не используете;
- обращайте внимание на дату последнего использования.
Тестирование перед развертыванием
- Тестируйте на loopback-адресе — используйте
http://127.0.0.1:PORTилиhttp://localhost:PORTкак Redirect URI. - Проверяйте обработку ошибок — убедитесь, что приложение корректно обрабатывает все коды ошибок OAuth 2.0.
- Проверьте PKCE-flow — убедитесь, что code_verifier правильно вычисляется и передается.
- Тестируйте сценарий истечения токена — убедитесь, что refresh-flow работает корректно.