Исследование методов аутентификации пользователя для сайтов и API. Аутентификация по протоколу oAuth2.
- 00:02:39 - Allow
- 00:03:19 - Unauthorized
- 00:04:24 - Basic Auth
- 00:11:37 - Bearer Auth
- 00:15:53 - OAuth2
- 00:16:53 - OAuth2 Password Grant
- 00:20:26 - OAuth2 Refresh Token Grant
- 00:21:57 - Аутентификация через социальную сеть
- 00:26:34 - OAuth2 Authorization Code Grant
- 00:27:55 - OAuth2 Token Mode
- 00:28:25 - OAuth2 Code Mode
- 00:29:43 - Session Auth
- 00:31:53 - "Remember me" Cookie Auth
- 00:32:29 - Cookie Auth
- 00:35:09 - Подведение итогов
Скрытый контент (код, слайды, ...) для подписчиков.
Открыть →Чтобы не пропускать новые эпизоды подпишитесь на наш канал @deworkerpro в Telegram
Почему-то именно в этом видео отсутствует регулятор звука.
Весьма странный плеер. Фронтенд как всегда радует :)
А можно рассказать про OIDC?
Это тот же рассмотренный нами OAuth2, который дополнительно при указании
scope=openid
возвращает ещё один ID-токен формата JWT с данными пользователя.Спасибо.
Толково и кратко!, благодарю. А вопросы таковы :
нужно ли думать как удалять накопившиеся файлы сессий на сервере или работает автоматический надёжный механизм для их очистки?
Верно ли я понял, что если нужно надёжно разлогинивать пользователей после произвольного времени, то нужно костылить куки в дополнении к сессии, так как сами сессии не имеют нужных таймаутов. Или уже использовать аутентификацию по токенам ?
В PHP сессии автоматически чистятся по Cron через время
session.gc_maxlifetime
изphp.ini
По умолчанию установлено 30 минут.
Куки устанавливаются автоматически на время
session.cookie_lifetime
Спасибо. А как правильно быстро отменить сессию (запретить вход по старому паролю) не дожидаясь тайм-аута, например после смены пароля пользователя администратором?
Можно хранить сессии в базе данных в таблице
sessions(id,user_id,expires,value)
. И при смене пароля сразу по полюuser_id
всё удалять. Но тогда надо сделать ручную очистку через Cron по полюexpires
, чтобы база не переполнялась.Дмитрий, а верно ли моё предположение, что аутентификация пользователя через сессии будет работать только с GET запросами из браузера, а с POST запросами (через POST ajax из того же броузера) - не будет?
Вроде как броузер не контролирует куки при POST запросах.
Если да, то как посоветуете контролировать безопасность POST запросов?
ПС: Я засомневался, потому что видел такой чужой костыль:
Перед отрисовкой формы (GET) , гетерится случайное число (типа токен) и записывается в сессию + сохраняется в скрытое поле формы. А при POST из этой формы этот "токен" из скрытого поля отправляется на backend в JSON с прочими данными и уже на backend сравнивается с тем же токеном из сессии.
Куки по умолчанию не отправляются в Ajax-запросах. Чтобы они добавлялись нужно в JavaScript для
fetch
илиaxios
включать параметрwithCredentials
.Значит злоумышленник может отправить злонамеренный post запрос не будучи авторизован и запрос будет обработан на бэкенде? А как защититься от этого?
Как раз для защиты CSRF в форму и куки добавляется случайный токен, чтобы не получилось отправить форму с другого сайта напрямую через
<form action="ваш сайт">
или Ajax-запросом из JavaScript.Чтобы Ajax-запрос учитывал куки нужно на клиенте в JavaScript включить
withCredentials
. Но при POST-запросе из-за наличия в запросе заголовка Cookie браузер сразу включает защиту CORS, рассмотренную в следующих скринкастах. Тогда он отправит сначала OPTINS запрос и проверит, что в ответе сервера естьAccess-Control-Allow-Credentials
. И уже после этого отправит настоящий POST-запрос с куками.Так что для защиты от POST-запросов с чужих сайтов достаточно добавить скрытое поле и куку. Браузер нас защитит сам.
Но если злоумышленник отправляет запросы не через браузер, а напрямую из HTTP-клиента, то защититься можно только капчей.
Да, этот случай.
Но ведь капчей может пользоваться только человек, причем желательно не слепой/глухой. А если мы ждем нападения POST роботов? Или открываем наружу свой API с POST запросами по какому-то url?
В этих случаях защитит только токен? Надежно?
С прошедшим днем учителя Вас и Юлию !!!
Токен защищает только от HTML-форм или Ajax запросов с других сайтов в браузере. Другие HTTP-клиенты смогут спокойно получать и отправлять куку с этим токеном.
Тогда никак. Можем ограничивать число запросов в минуту с одного IP.
Для аутентиифицированных запросов можем банить аккаунты спамеров. А от гостевых запросов от роботов можно защититься только капчей.
Спасибо, Дмитрий!
Хочу Вас правильно понять.
Из Ваших слов я заключаю, что невозможно защитить приложение от враждебных POST запросов, если злоумышленник не пользуется броузером.
Звучит странно, т.к. банки, что позволяют работать клиентам без двухфакторной аутентификации уже разорились бы.
Приведу пример, который вроде как должен надежно защищать от таких атак.
У нас есть HTML страничка, на которой авторизованный пользователь жмет кнопку для совершения платежа.
Наш код по url этой страницы отправляет POST запрос на совершение этого платежа. Без разницы как отправляет: или form submit средствами броузера, или fetch из JavaScript.
Чтобы пресечь злодеяния, мы при формировании странички/формы записываем одноразовый свежий токен в скрытое поле, одновременно записывая его и в сессию. Это происходит при get запросе этой страницы авторизованым пользователем. Авторизация пользователя - по хешированому паролю из сессии.
Пользователь жмет кнопку "оплатить" и наша форма отправляет post запрос на url этой же страницы. Причем запрос отправляется с упомянутым выше токеном.
В handler мы сверяем два значения токена: сохраненный в сессии и прилетевшый в POST запросе. Вот и вся проверка.
И как же ее обойдет внешний злодей с http клиентом?
Пусть он знает url страницы и данные для платежа. Пусть он может отправить post запрос через http клиент без POST авторизации. Но как он узнает свежий токен на странице, если он не авторизовался на ней по get запросу?
Я явно что-то не понимаю.
Сначала отправит GET запрос и спарсит куку сессии и скрытое поле.
Потом отправит POST с этими данными.
Отправляю запрос через postman:
Получаю в ответ куку и страницу логина.
Скрытое поле формы с токеном я увижу только если смогу авторизоваться.
Что тут можно спарсить для взлома ?
прилетело в ответ:
1) кука
2) страницу логина:
Формы перевода в банках как раз доступны только свежезалогиненным клиентам, закрыты этими CSRF-токенами и работают с SMS-подтверждением. Так что взломщику Ajax-запросом с чужого сайта из браузера (или из Postman не зная пароля) что-то отправить с чужого счёта на свой не получится.
Но ради забавы спамер может залогиниться в свой аккаунт, скопировать куку в свой скрипт и наотправлять миллион переводов между своими счетами без подтверждения. Банку будет всё равно. Хотя может забанить на сутки за подозрительно большое число операций.
Эта форма как раз без CSRF-токена, так что её можно заспамить с других сайтов. Достаточно сделать на любом бесплатном хостинге страницу
photo.html
с кодом вроде:Потом зайти на популярный форум и отправить сообщение с этим адресом:
Из браузеров тысяч читателей в форму банка прилетят миллионы запросов и он разорится на SMS-ках.
Спасибо!
Из Вашего пояснения я понял главное: что форма выплат с токеном, что находится за этой login страницей, всё-же находиться в безопасности, если злоумышленник не знает логина юзера.
Да, фронтальную логин форму можно заспамить, но это пустяк по сравнению с возможностью спереть деньги.
Теперь я спокоен :)
Благодарю, Дмитрий, за озвученные сценарии взлома! Применю для защиты.
Или войти через: