CSK-токен необхідний при використанні автентифікації без громадянства (= без сесії)?


125

Чи потрібно використовувати захист CSRF, коли програма покладається на автентифікацію без стану (використовуючи щось на зразок HMAC)?

Приклад:

  • У нас є один додаток сторінки ( в іншому випадку ми повинні додати маркер на кожному посиланні: <a href="...?token=xyz">...</a>.

  • Користувач аутентифікує себе за допомогою POST /auth. Після успішної аутентифікації сервер поверне деякий маркер.

  • Маркер буде зберігатися через JavaScript в деякій змінній всередині додатка на одній сторінці.

  • Цей маркер буде використовуватися для доступу до таких обмежених URL-адрес /admin.

  • Маркер завжди передаватиметься в заголовки HTTP.

  • НЕ Http сесії, а також немає файлів cookie.

Наскільки я розумію, не повинно бути (?!) можливості використовувати міжміські атаки, оскільки браузер не зберігатиме маркер, а значить, не може автоматично надсилати його на сервер (ось що буде при використанні файлів cookie / Сесія).

Я щось пропускаю?


6
Будьте уважні до Basic Auth. Багато браузерів автоматично надсилають основні заголовки аутентифікації на весь час сеансу. Це може зробити базовий auth настільки вразливим для CSRF, як auth cookie.
філаї

Відповіді:


159

Я знайшов деяку інформацію про CSRF +, не використовуючи файли cookie для аутентифікації:

  1. https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
    "оскільки ви не покладаєтесь на файли cookie, вам не потрібно захищати від запитів між веб-сайтами"

  2. http://angular-tips.com/blog/2014/05/json-web-tokens-introduction/
    "Якщо ми підемо вниз по шляху cookie, вам дійсно потрібно зробити CSRF, щоб уникнути перехресних запитів на сайт. Це те, що ми можемо забудь, коли ти будеш бачити JWT. "
    (JWT = Json Web Token, аутентифікація на основі токена для додатків без стану)

  3. http://www.jamesward.com/2013/05/13/securing-single-page-apps-and-rest-services
    "Найпростіший спосіб зробити аутентифікацію без ризику вразливості CSRF - просто уникати використання файлів cookie для ідентифікації користувача "

  4. http://sitr.us/2011/08/26/cookies-are-bad-for-you.html
    "Найбільша проблема CSRF полягає в тому, що файли cookie абсолютно не захищають від цього типу атаки. Якщо ви використовуєте автентифікацію файлів cookie Ви також повинні застосувати додаткові заходи для захисту від CSRF. Найголовніша обережність, яку Ви можете вжити, - це переконатися, що Ваша заявка ніколи не виконує жодних побічних ефектів у відповідь на GET-запити. "

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


Якщо вам потрібно запам'ятати користувача, є два варіанти:

  1. localStorage: Магазин ключових значень браузера. Збережені дані будуть доступні навіть після того, як користувач закриє вікно браузера. Дані не доступні для інших веб-сайтів, оскільки кожен сайт отримує власне сховище.

  2. sessionStorage: Також у сховищі даних браузера. Різниця полягає в тому, що дані видаляються, коли користувач закриває вікно браузера. Але це все-таки корисно, якщо ваш веб-сайт складається з декількох сторінок. Тож ви можете зробити наступне:

    • Користувач входить у систему, потім ви зберігаєте маркер у sessionStorage
    • Користувач натискає на посилання, яке завантажує нову сторінку (= реальне посилання та не замінює вміст javascript)
    • Ви все одно можете отримати доступ до маркера з sessionStorage
    • Щоб вийти з системи, ви можете видалити маркер вручну sessionStorageабо зачекати, коли користувач закриє вікно браузера, яке очистить усі збережені дані.

(для обох дивіться тут: http://www.w3schools.com/html/html5_webstorage.asp )


Чи існують офіційні стандарти для аутентифікації маркера?

JWT (Json Web Token): Я думаю, що це ще проект, але його вже використовують багато людей, і концепція виглядає простою та безпечною. (IETF: http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25 )
Також є бібліотеки для фреймворку лотів. Просто Google для цього!


37
Чудовий підсумок CSRF! Зауважу, що зберігання ваших жетонів у localStorage або sessionStorage є вразливим до атак XSS і дані можуть переглядатись сценаріями на сторінці, тому якщо у вас є компрометований скрипт, який подається з CDN або якщо в одному з ваших є зловмисний код Бібліотеки JS, вони можуть вкрасти маркер із цих місць зберігання. Дивіться: stormpath.com/blog/… Я думаю, що найбільш безпечним підходом є збереження JWT + CSRF маркера у файлі cookie, а потім розмістити обчислений JWT з токеном CSRF всередині нього у заголовку запиту.
Аарон Грей

Щодо: "Найголовніша обережність, яку ви можете вжити, - це переконатися, що ваша програма ніколи не виконує жодних побічних ефектів у відповідь на GET-запити." Чи можлива атака CSRF підробляти запит POST?
Коста

Залежно від додатка на стороні сервера, МОЖЕ бути можливим. Є веб-рамки, які використовують щось подібне http://.../someRestResource?method=POST. Таким чином, це в основному GETзапит, але серверна програма інтерпретує це як POSTзапит, оскільки він був налаштований використовувати methodпараметр замість заголовка HTTP. ...Що стосується загальноприйнятих веб-браузерів, вони застосовують політику тієї ж оригіналу та виконуватимуть GETзапити лише до іноземних серверів. Хоча можна виконати POSTзапити, якщо веб-браузер не застосовує ці веб-стандарти (помилка, зловмисне програмне забезпечення).
Бенджамін М

1
Додавання до Server Side App: Надіслати орган запиту досі неможливо, оскільки звичайні браузери цього не дозволяють. Однак якщо серверне додаток дозволяє method=POST, це може також дозволити body={someJson}змінити тіло запиту за замовчуванням. Це дійсно поганий дизайн API і надзвичайно ризиковано. Хоча, якщо ваш серверний додаток дозволяє, http://...?method=POST&body={someJson}вам слід дійсно переосмислити, що ви там робили, і чому, і якщо це взагалі необхідно. (Я б сказав, що в 99,9999% випадків це не потрібно). Крім того, браузери можуть надсилати таким чином лише кілька кілобайт.
Бенджамін М

@BenjaminM зауважує, що однакова політика щодо оригіналу не дозволяє коду javaScript отримати доступ до результату, тому, хоча запит "заблокований", він фактично дістається до сервера - jsbin.com/mewaxikuqo/edit?html,js,output Я протестував це лише на firefox, але ви можете відкрити інструменти розробки і побачити, що навіть через те, що ви отримаєте "Перехресний запит заблокований", віддалений сервер насправді бачить весь запит. тому для всіх ваших POST-запитів ви повинні мати жетони або користувацькі заголовки (і, якщо можливо, обидва)
Yoni Jah

59

TL; DR

JWT, якщо використовується без файлів cookie, заперечує необхідність маркер CSRF - АЛЕ! зберігаючи JWT у сесії / localStorage, викрийте свій JWT та ідентифікацію користувача, якщо ваш сайт має вразливість XSS (досить поширене). Краще додати csrfTokenключ до JWT та зберігати JWT у файлі cookie з набором secureта http-onlyатрибутами.

Прочитайте цю статтю з хорошим описом для отримання додаткової інформації https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage

Ви можете зробити цей захист CSRF без стану, включивши заявку XsrfToken JWT:

{ "iss": "http://galaxies.com", "exp": 1300819380, "scopes": ["explorer", "solar-harvester", "seller"], "sub": "tom@andromeda.com", "xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e" }

Таким чином, вам потрібно буде зберігати csrfToken в localStorage / sessionStorage, а також у самому JWT (який зберігається у файлі cookie, призначеному лише для http). Потім для захисту csrf переконайтеся, що маркер csrf у JWT відповідає поданому заголовку csrf-token.


2
Чи слід вилучати використання маркера csrf під час аутентифікації користувача api?
user805981

3
Варто зазначити (як інші також згадували у коментарях до посилання на джерело), ​​що будь-яке пом'якшення наслідків CSRF, яке використовує a) файли cookie, які не є лише http або b) зберігає маркер CSRF у локальному сховищі, є вразливим для XSS. Це означає, що представлений підхід може допомогти зберегти JWT в таємниці від зловмисника за допомогою XSS, але зловмисник все одно зможе виконати зловмисний запит у вашому API, оскільки він може надати дійсний JWT (за допомогою файлу cookie, дякую веб-переглядачу) та маркер CSRF (читати через введений JS з локального сховища / cookie).
Йоханнес Рудольф

1
Насправді навіть маркер CSRF не може захистити вас на цьому рівні XSS, оскільки ви припускаєте, що зловмисник може отримати доступ до localStorage, єдиний на даний момент спосіб доступу - це доступ до рівня скрипту, який вони так чи інакше можуть переглядати маркер CSRF. .
недійсне

1
Хіба це не те, що говорив @JohannesRudolph? Як тільки ви зберігаєте маркер CSRF у файлі cookie веб-сховища / не лише http, ви збільшуєте свій слід атаки XSS, оскільки вони доступні через JS.
adam-beck

1
Тут не є тотальним експертом, але якщо ви все ще піддаєтесь дії XSS, як ви були на початку, я не впевнений, що частину краще додати ... дійсно справедливо. Напевно, зловмиснику трохи складніше (отримати?) Маркер CSRF, але він врешті-решт зможе виконати запит від вашого імені, навіть не знаючи маркер JWT. Це правильно? Спасибі
superjos
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.