Як захистити JWT-токени: Посібник з найкращих практик

JSON Web Tokens (JWT) стали галузевим стандартом для безсерверної аутентифікації. Вони дозволяють серверам перевіряти ідентичність користувача без зберігання даних сесії на самому сервері. Однак ця безсерверна природа ускладнює безпеку, якщо реалізувати це неправильно. У цьому посібнику ми розглянемо, як належним чином захистити JWT-токени для захисту даних користувача та підтримки цілісності програми.

Розуміння структури JWT

Перед переходом до заходів безпеки важливо розуміти три частини JWT: заголовок, корисне навантаження (payload) та підпис.

  1. Заголовок (Header): Містить алгоритм, використовуваний для підпису токена (наприклад, HS256, RS256).
  2. Корисне навантаження (Payload): Містить заяви (дані про користувача, такі як ID та роль).
  3. Підпис (Signature): Забезпечує, що токен не був змінений.

Оскільки payload закодовано у форматі base64, його може прочитати будь-хто, хто перехопить токен. Саме тому заходи безпеки, такі як HTTPS та перевірка підпису, є невід'ємними.

1. Завжди використовуйте HTTPS

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

BBBA підкреслює, що використання HTTPS є обов'язковим для запобігання атакам зловмисника посередині (Man-in-the-Middle). Це шифрування гарантує, що токен залишиться конфіденційним з моменту його відправлення клієнтом до моменту надходження на сервер.

2. Безпечно зберігайте секрети підпису

Підпис — це єдине, що підтверджує автентичність токена. Для генерації валідного підпису потрібен секретний ключ (для симетричних алгоритмів) або приватний ключ (для асиметричних алгоритмів).

Не вшивайте секрети в код

Одна з найпоширеніших помилок розробників — вшивання секретного ключа безпосередньо у вихідний код. Якщо ваш код опубліковано в відкритому репозиторії (наприклад, GitHub), секрет стає вразливим. H2S Media радить уникати цієї практики, пропонуючи замість цього використовувати змінні середовища (environment variables) для зберігання секретів. Це дозволяє тримати чутливі дані окремо від логіки програми та запобігає випадковому розголошенню.

Регулярно змінюйте секрети

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

3. Оберіть правильний механізм зберігання

Те, де ви зберігаєте JWT на стороні клієнта, є критичним рішенням щодо безпеки. Два основні варіанти — LocalStorage та HttpOnly Cookies.

Ризики LocalStorage

Зберігання JWT у localStorage робить їх доступними для будь-якого JavaScript, що працює на сторінці. Якщо у вашій програмі є вразливість Cross-Site Scripting (XSS), атакуючий може легко вкласти токен та імітувати користувача. MakeUseOf підкреслює, що хоча localStorage зручний, він вразливий до XSS-атак.

Безпека HttpOnly Cookies

HttpOnly cookies недоступні через JavaScript. Це робить їх імунними до XSS-атак, що намагаються вкласти токен. Для максимальної безпеки, особливо в програмах, що обробляють чутливі дані, зберігання JWT у HttpOnly cookie є рекомендованим підходом. Цей метод також допомагає мінімізувати атаки Cross-Site Request Forgery (CSRF), якщо поєднати його з належними атрибутами SameSite.

4. Впровадьте короткі терміни дії

JWT призначені для роботи в безсерверному режимі, тобто вони валідні до закінчення терміну дії. Однак чим довше токен валідний, тим вищий ризик, якщо його перехоплять. AWS рекомендує використовувати короткі терміни дії для токенів доступу. Залишаючи TTL (Time To Live) коротким, ви обмежуєте шкоду, яку може завдати атакуючий, якщо йому вдасться вкласти токен.

Шаблон токена оновлення

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

5. Обробка відклику токенів

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

Короткий TTL як стратегія відклику

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

Чорний список (Blacklist)

Для програм, які вимагають миттєвого відклику, можна впровадити станний чорний список. Коли користувач вийшов або його сесія недійсна, ви додаєте ID токена (JTI) до бази даних або кешу. Перед перевіркою токену сервер перевіряє, чи знаходиться JTI у чорному списку. Однак цей підхід вимагає підтримки стану, що суперечить безсерверній природі JWT.

6. Перевірка заявок токенів

Коли ви отримуєте JWT, ваш сервер повинен виконувати ретельну перевірку. AWS детально описує важливість перевірки заявок Issuer (видавець), Audience (аудиторія) та Expiration (термін дії).

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

7. Розгляньте альтернативи, такі як PASETO

Хоча JWT широко використовуються, у них є історія вразливостей безпеки. Наприклад, вразливість алгоритму "none" дозволяла атакуючим підроблювати токени. HackerNoon обговорює підйом PASETO (Platform for Authentication, Security, and Encryption of Tokens), нового стандарту токенів, призначеного для вирішення вразливостей JWT. PASETO підтримує як симетричні, так і асиметричні ключі та розроблений так, щоб бути безпечним за замовчуванням. Хоча JWT все ще є стандартом, розуміння альтернатив, таких як PASETO, критично для архітекторів, які приймають довгострокові рішення.

Поширені запитання

Яка різниця між HS256 та RS256?

HS256 (HMAC з SHA-256) використовує спільний секретний ключ між клієнтом та сервером. RS256 (RSA з SHA-256) використовує приватний ключ для підпису токена та публічний ключ для його перевірки. RS256 зазвичай вважається безпечнішим для розподілених систем, оскільки приватний ключ ніколи не покидає сервер.

Чи можу я відкликати JWT миттєво?

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

Чи безпечно використовувати LocalStorage для JWT?

Ні, LocalStorage вразливий до XSS-атак. Якщо ваша програма буде скомпрометовано, атакуючий може прочитати LocalStorage і вкласти JWT. HttpOnly cookies є рекомендованим механізмом зберігання для безпеки.

Висновок

Захист JWT вимагає комплексного підходу. Використовуючи HTTPS, безпечно керуючи секретами, зберігаючи токени у HttpOnly cookies, впроваджуючи короткі терміни дії та ретельно перевіряючи заявки, ви можете суттєво знизити ризик вкрадення та неправомірного використання токенів. З розвитком веб-безпеки важливо бути в курсі найкращих практик та альтернатив, таких як PASETO, для підтримки надійної позиції безпеки.

Джерела

  1. JWT vs PASETO: What's the Best Tool for Generating Secure Tokens?
  2. How to Build a Secure Nest.js REST API Using JWT and MongoDB
  3. How to secure API Gateway HTTP endpoints with JWT authorizer
  4. Best of 2021 – How to Revoke JSON Web Tokens (JWTs)
  5. JSON Web tokens (JWT): how to use them safely
  6. How to Create a JWT Secret in Node.js (Best Practices + Examples)
  7. How to monitor, optimize, and secure Amazon Cognito machine-to-machine authorization