1

Тема: Чи обов'язково серверне печиво повинно бути HttpOnly ?

Вітаю.
З самого початку я використовував JWT для автентифікації користувачів на сервері.
Тобто, при логіні користувача, сервер відправляв токен, котрий зберігався в localStorage клієнта, і коли клієнту треба було відправити якийсь запит, то він також відправляв той токен, а сервер вже перевіряв, чи той токен валідний, і якщо так, то все ок.

Тепер я замінив JWT на сесію, котра використовує куклуси, тобто куки, тобто печиво, ну, кукєзи.
Працює воно ось так:
Коли клієнт логіниться, сервер перевіряє, чи такий користувач існує в БД, і якщо так, то до хедерів відповіді сервера додається Set-Cookies з кукізами, котрі з себе представляють унікальний текстовий рядок.
Коли ця відповідь приходить до клієнта, то воно зберігається в cookies самим браузером, і наступні запити до сервера місцять ті куки в хедері, але я якось хочу зрозуміти на клієнті - коли клієнта залогінений, а коли ні.
Для цього я хотів би мати змогу перевірити, чи є у нас якісь куки, але коли я намагаюсь прочитати їх, то мені не показуються ті куки, котрі прийшли з серверу.

Я помітив, що ці куки мають прапорець HttpOnly, і виявляється, що через це вони недоступні для читання на стороні клієнта.
Так от я думаю, чи це мені треба просто зкидувати цей прапорець ще на сервері, перед відправленням їх клієнту, чи так робити дуже погано, і я щось роблю зовсім неправильно?

2

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

Навіть коли в тебе є куки, то не значить, що ти залогінений, бо при наступному запиті сервер може вирішити, що фатить. Краще зробити обробку відповіді, що користувач не авторизований.

Подякували: leofun011

3

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

так я так і хотів зробити, якщо неавторизований, то видаляємо куки, а якщо куки є - то нехай буде авторизований.
Бо ми ж можемо залогінитись, а потім закрити вкладку, а потім відкрити її знову, і треба вирішити, що показати користувачу, поки перший запит до серверу виконається

4

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

Це якийсь M$івський захист від script kiddies.
https://www.owasp.org/index.php/HttpOnl … g_HttpOnly
Як на мене, воно не дуже впливає на безпеку, а от на зручність дебагу - можуть. Десь як табличка "вхід лише для персоналу".

Подякували: FakiNyan, leofun012

5

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

то краще при вдалому логіні просто записувати в localStorage  { auth: true }, а при виході, або після запиту, що поверне помилку про невдалу авторизацію, записувати { auth: false }, або просто видаляти той запис?

6

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

чи то ви кажете, що оті куки взагалі не дуже впливають на безпеку? а що тоді впливає? бо раніше був JWT, так його ж можна було просто зкопіювати, і підставляти в свої запити.
Та й в будь-якому разі нам потрібно відправляти на сервер щось, що дозволяло б серверу розуміти, чи то є авторизований юзер, чи ні, а для цього це "щось" потрібно зберігати на стороні клієнта, або в куках, або в localStorage, або в IndexexDB, чи ще десь там, але суть в тому, що оте "щось" все одно можна буде дістати на стороні клієнта і зкопіювати, а потім робити з ним щось не дуже добре.

7

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

тобто httpOnly, то фігня, і можна на нього забити, і відправляти без нього?

8

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

JWT має жити 1-5 хв, макс 10хв. Ще має бути другий refresh токен.

9

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

Q-bart написав:

JWT має жити 1-5 хв, макс 10хв. Ще має бути другий refresh токен.

це загалом, чи в конкретній ситуації? і що то за refresh token?

10

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

Я лінивий гуглити, але з того що пригадую, то визначається чи будуть шаритись куки між http і https запитами до того самого домену.

11

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

FakiNyan написав:
Q-bart написав:

JWT має жити 1-5 хв, макс 10хв. Ще має бути другий refresh токен.

це загалом, чи в конкретній ситуації? і що то за refresh token?

Один раз залогінився на сервері авторизації по захищеному каналу, і потім з рефреш токеном кожні 5 хвилин обновляєш свій токен доступу, щоб знов не слати логін і пароль. По факту зроблено, щоб не треба було ніде зберігати логін і пароль. А в разі якщо хтось десь перехопить рефреш токен, то його просто заносять в чорний список і більше не приймають. Користувач ще раз логіниться з логіном і паролем без потреби їх зміни.

Подякували: Q-bart, leofun012

12

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

так а хіба не можна просто взяти копію того токена, разом з рефреш токеном, і підставляти в свої запити?
чи не легче з сесійним токеном вовтузитись? коли юзер вилогунюється, то куки просто видаляються з бази даних на сервері, і якщо хтось був вкрав ті куки, то вони вже не дійсні

13 Востаннє редагувалося Vo_Vik (24.10.2018 15:17:32)

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

Так давай не путати куки з рефреш токеном від JWT.

При jwt у тебе є сервер авторизації, який може бути фігзна де. Веб сервер просто довіряє інформації в цьому токені за рахунок звірки підписів.

Якщо використовуєш куки, і PHP сесію, то вся інформація про користувача, в тому числі авторизований він чи ні зберігається на серваку, а куки це просто унікальний хеш який каже серверу де саме та інформація зберігається. Куки сесії в тебе будуть завжди, при будь якому запиті до сервака де є PHP, навіть якщо там нема ніяких логінів і паролів, хіба би хтось дуже пострадав міняти конфіги, щоб вони взагалі не відправлялись нікому.
Вірніше трохи не так. В PHP є функція старт сешн, яка і встановлює ці куки. Якщо говорити про 99.9% фрейморків, то вона викликається при обробці будь-якого запиту.

Подякували: leofun011

14 Востаннє редагувалося FakiNyan (24.10.2018 15:22:26)

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

так в мене не PHP, а нода з express.
куки то відправляються навіть і не при логіні, але лише при логіні вони заносяться до бази даних, і лише після цього запити з цими куками вважаються авторизованими

15

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

Vo_Vik написав:
FakiNyan написав:
Q-bart написав:

JWT має жити 1-5 хв, макс 10хв. Ще має бути другий refresh токен.

це загалом, чи в конкретній ситуації? і що то за refresh token?

Один раз залогінився на сервері авторизації по захищеному каналу, і потім з рефреш токеном кожні 5 хвилин обновляєш свій токен доступу, щоб знов не слати логін і пароль. По факту зроблено, щоб не треба було ніде зберігати логін і пароль. А в разі якщо хтось десь перехопить рефреш токен, то його просто заносять в чорний список і більше не приймають. Користувач ще раз логіниться з логіном і паролем без потреби їх зміни.

Навіть більше, читав про таку схему, коли:
1. сервер видав JWT + refresh
2. робим запити з JWT, робим, робим
3. прийшов 401 - помилка, треба рефрешнутись
4. робим запит на refresh: на сервері видається новий JWT, refresh видаляється!!!, створюється новий refresh, повертається все на фронт назад.
5. далі робим запити.
6. якщо хтось вкрав твій рефреш + jwt (а ти зараз не в системі, і не робиш запитів взагалі) :- то може ними користуватись багато часу.
- робить запити, запитити...
- рефреш. Робить refresh запит, отримує новий jwt, новий refresh - з ними далі робить запити

7. Коли наш юзер знову захоче зайти на сервер:
- робить запит з jwt - повертається 401
- робить запит на рефреш з тим токеном, що має - токен вже не валідний, в БД знайти його не можна оскілько злочинець вже з ним рефрешнувся.
- юзеру залишається лише ввести login/pass, сервер бачить, що це той хто треба, видає JWT, створює новий refresh, старий, що згенерувався злочинцем видаляється (все злочинець більше ніколи не отримає доступу з вкраденими даними)

Тому така схема, мінімізує можлививй час використання вкрадених токенів для отримання доступу, до того до чого тобі не треба.

ps. Лише, можливості бути залогованим в двох різних браузерах (мобайл + веб) нема. Ну або щось додумати можна.

Подякували: leofun011

16

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

Ти впевнений, що воно пише в базу? Нє ну можна сесії і в базі зберігати, але переважно їх тримають де інде. І сесія створюється і для не авторизованого користувача і зберігається на сервері. Основне завдання сесій зберігання даних між запитами. Авторизація то вже наслідок

17 Востаннє редагувалося Vo_Vik (24.10.2018 15:44:02)

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

Q-bart написав:
Vo_Vik написав:
FakiNyan написав:

це загалом, чи в конкретній ситуації? і що то за refresh token?

Один раз залогінився на сервері авторизації по захищеному каналу, і потім з рефреш токеном кожні 5 хвилин обновляєш свій токен доступу, щоб знов не слати логін і пароль. По факту зроблено, щоб не треба було ніде зберігати логін і пароль. А в разі якщо хтось десь перехопить рефреш токен, то його просто заносять в чорний список і більше не приймають. Користувач ще раз логіниться з логіном і паролем без потреби їх зміни.

Навіть більше, читав про таку схему, коли:
1. сервер видав JWT + refresh
2. робим запити з JWT, робим, робим
3. прийшов 401 - помилка, треба рефрешнутись
4. робим запит на refresh: на сервері видається новий JWT, refresh видаляється!!!, створюється новий refresh, повертається все на фронт назад.
5. далі робим запити.
6. якщо хтось вкрав твій рефреш + jwt (а ти зараз не в системі, і не биш запитів взагалі) :- то може ними користуватись багато часу.
- робить запити, запитити...
- рефреш. Робить refresh запит, отримує новий jwt, новий refresh - з ними далі робить запити

7. Коли наш юзер знову захоче зайти на сервер:
- робить запит з jwt - повертається 401
- робить запит на рефреш з тим токеном, що має - токен вже не валідний, в БД знайти його не можна оскілько злочинець вже з ним рефрешнувся.
- юзеру залишається лише ввести login/pass, сервер бачить, що це той хто треба, видає JWT, створює новий refresh, старий, що згенерувався злочинцем видаляється (все злочинець більше ніколи не отримає доступу з вкраденими даними)

Тому така схема, мінімізує можлививй час використання вкрадених токенів для отримання доступу, до того до чого тобі не треба.

ps. Лише, можливості бути залогованим в двох різних браузерах (мобайл + веб) нема. Ну або щось додумати можна.

JWT і їхні рефреш токени не зберігаються в базі, в них є час придатності до якого вони дійсні, якщо треба заборонити якийсь, то його заносять в блекліст до часу його придатності. Цим мінімізується розмір того що зберігається. Навіть не самі токени заносяться в блекліст, а просто кажеться, що все що видано цьому юзеру до такого то таймстемпу - невалідне.

18

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

Vo_Vik написав:

Ти впевнений, що воно пише в базу? Нє ну можна сесії і в базі зберігати, але переважно їх тримають де інде. І сесія створюється і для не авторизованого користувача і зберігається на сервері. Основне завдання сесій зберігання даних між запитами. Авторизація то вже наслідок

так я цю фічу сам підключав, якщо без неї, то сесії тримаються в пам'яті серверу, і якщо його перезавантажити, то все втрачається, тому вони кудись зберігаються, там можна зберігати їх як файли в папці, а можна в бд.

19

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

Vo_Vik написав:
Q-bart написав:
Vo_Vik написав:

Один раз залогінився на сервері авторизації по захищеному каналу, і потім з рефреш токеном кожні 5 хвилин обновляєш свій токен доступу, щоб знов не слати логін і пароль. По факту зроблено, щоб не треба було ніде зберігати логін і пароль. А в разі якщо хтось десь перехопить рефреш токен, то його просто заносять в чорний список і більше не приймають. Користувач ще раз логіниться з логіном і паролем без потреби їх зміни.

Навіть більше, читав про таку схему, коли:
1. сервер видав JWT + refresh
2. робим запити з JWT, робим, робим
3. прийшов 401 - помилка, треба рефрешнутись
4. робим запит на refresh: на сервері видається новий JWT, refresh видаляється!!!, створюється новий refresh, повертається все на фронт назад.
5. далі робим запити.
6. якщо хтось вкрав твій рефреш + jwt (а ти зараз не в системі, і не биш запитів взагалі) :- то може ними користуватись багато часу.
- робить запити, запитити...
- рефреш. Робить refresh запит, отримує новий jwt, новий refresh - з ними далі робить запити

7. Коли наш юзер знову захоче зайти на сервер:
- робить запит з jwt - повертається 401
- робить запит на рефреш з тим токеном, що має - токен вже не валідний, в БД знайти його не можна оскілько злочинець вже з ним рефрешнувся.
- юзеру залишається лише ввести login/pass, сервер бачить, що це той хто треба, видає JWT, створює новий refresh, старий, що згенерувався злочинцем видаляється (все злочинець більше ніколи не отримає доступу з вкраденими даними)

Тому така схема, мінімізує можлививй час використання вкрадених токенів для отримання доступу, до того до чого тобі не треба.

ps. Лише, можливості бути залогованим в двох різних браузерах (мобайл + веб) нема. Ну або щось додумати можна.

JWT і їхні рефреш токени не зберігаються в базі, в них є час придатності до якого вони дійсні, якщо треба заборонити якийсь, то його заносять в блекліст до часу його придатності. Цим мінімізується розмір того що зберігається. Навіть не самі токени заносяться в блекліст, а просто кажеться, що все що видано цьому юзеру до такого то таймстемпу - невалідне.

JWT - ні, його можна підписати. А refresh - uuid і зберігаєм в БД

20

Re: Чи обов'язково серверне печиво повинно бути HttpOnly ?

оце в мене зараз сесія використовує uuid, і зберігає то в бд