Код-ревью Senior Аутентификация и сессии обновлено
Ревью: callback OAuth на Python
Вопрос
Найдите проблемы в обработчике входа через внешнего провайдера (OIDC).
@app.get("/oauth/callback")
def callback():
code = request.args["code"]
tokens = requests.post(TOKEN_URL, data={
"grant_type": "authorization_code", "code": code,
"redirect_uri": request.args.get("redirect_uri", DEFAULT_REDIRECT),
"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET,
}).json()
claims = jwt.decode(tokens["id_token"], options={"verify_signature": False})
user = find_or_create(email=claims["email"])
session["user_id"] = user.id
return redirect(request.args.get("next", "/"))
Коротко
OIDC безопасен, только если выполнены все проверки протокола. Связывать аккаунты лучше по паре (issuer, sub), а email использовать только подтверждённый.
Что должен найти ревьюер
- Безопасностьстрока 3Не проверяется параметр
state: CSRF на callback, атакующий может залогинить жертву в свой аккаунт. - Безопасностьстрока 6
redirect_uriберётся из запроса, а должен быть фиксированным и совпадать с зарегистрированным. - Безопасностьстрока 9Подпись ID-токена не проверяется, а также
iss,aud,exp,nonce: токен можно подделать. - Безопасностьстрока 10Пользователь ищется по email без проверки
email_verifiedи без привязки кsubпровайдера: захват аккаунта через неподтверждённый email. - Безопасностьстрока 11Сессия не перевыпускается при входе.
- Безопасностьстрока 12Открытый редирект через
next. - Безопасностьстрока 4Нет PKCE (code_verifier) при обмене кода.
Разбор
OIDC безопасен, только если выполнены все проверки протокола. Связывать аккаунты лучше по паре (issuer, sub), а email использовать только подтверждённый.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.