Нам потрібно зберігати JWT на клієнтському комп'ютері. Якщо ми зберігаємо його в LocalStorage / SessionStorage, то його можна легко схопити нападом XSS. Якщо ми зберігаємо його у файлах cookie, то хакер може використовувати його (не читаючи) під час атаки CSRF і видавати себе за користувача, зв’язуватися з нашим API та надсилати запити на виконання дій або отримання інформації від імені користувача.
Але є кілька способів закріпити JWT у файлах cookie, щоб їх не вкрали легко (але все-таки є деякі передові методи їх викрадення). Але якщо ви хочете покластися на LocalStorage / SessionStorage, то до нього можна дістатися простою атакою XSS.
Тому для вирішення проблеми CSRF я використовую у своїй заяві «Double Submit Cookies».
Метод подвійного надсилання файлів cookie
Зберігайте JWT у файлі cookie HttpOnly і використовуйте його в захищеному режимі для передачі через HTTPS.
Більшість атак CSRF мають інше походження або заголовок реферала з оригінальним хостом у своїх запитах. Тож перевірте, чи є у вас якийсь із них у заголовку, вони надходять із вашого домену чи ні! Якщо не відхилити їх. Якщо і запит, і посилання, не доступні в запиті, не хвилюйтесь. Ви можете розраховувати на результат перевірки заголовка X-XSRF-TOKEN, який я пояснюю на наступному кроці.
Хоча браузер автоматично надає ваші файли cookie для домену запиту, є одне корисне обмеження: JavaScript-код, який працює на веб-сайті, не може читати файли cookie інших веб-сайтів. Ми можемо використовувати це для створення нашого рішення в галузі CSRF. Щоб запобігти атакам CSRF, ми повинні створити додатковий файл, який читається в JavaScript, який називається: XSRF-TOKEN. Цей файл cookie повинен бути створений, коли користувач увійшов у систему, і він повинен містити випадкову невідповідну рядок. Ми також зберігаємо це число в самому JWT як приватну претензію. Кожен раз, коли програма JavaScript хоче надіслати запит, потрібно буде прочитати цей маркер і надіслати його у власному заголовку HTTP. Оскільки ці операції (зчитування файлу cookie, встановлення заголовка) можна проводити лише в тому самому домені програми JavaScript,
Кутовий JS полегшує ваше життя
На щастя, я використовую Angular JS в нашій платформі та Angular пакетах підходу маркера CSRF, що робить його більш простим у здійсненні. Для кожного запиту, який робить наш $http
сервісний додаток Angular, служба Angular виконає такі дії автоматично:
- Шукайте файл cookie на ім'я XSRF-TOKEN у поточному домені.
- Якщо цей файл cookie знайдений, він зчитує значення та додає його до запиту як заголовок X-XSRF-TOKEN.
Таким чином, реалізація на стороні клієнта для вас обробляється автоматично! Нам просто потрібно встановити файл cookie XSRF-TOKEN
на поточному домені на стороні сервера, і коли наш API отримав будь-який дзвінок від клієнта, він повинен перевірити X-XSRF-TOKEN
заголовок і порівняти його з XSRF-TOKEN
JWT. Якщо вони відповідають, то користувач справжній. В іншому випадку це підроблений запит, і ви можете його проігнорувати. Цей метод натхненний методом "Подвійне надсилання файлів cookie".
Обережність
Насправді ви все ще сприйнятливі до XSS, це просто те, що зловмисник не може викрасти вам JWT-маркер для подальшого використання, але він все одно може робити запити від імені ваших користувачів за допомогою XSS.
Незалежно від того, чи зберігаєте ви свій JWT в localStorage
або ви зберігаєте свій XSRF-маркер у файлі cookie не HttpOnly, обоє можуть бути легко схоплені XSS. Навіть ваш JWT у файлі cookie HttpOnly можна схопити за допомогою вдосконаленої атаки XSS, як метод XST .
Отже, окрім методу "Double Submit Cookies", ви завжди повинні дотримуватися найкращих практик щодо XSS, включаючи вміст, що відмічається. Це означає видалити будь-який виконуваний код, який призведе до того, що браузер зробить те, чого ви не хочете. Зазвичай це означає видалення // <![CDATA[
тегів та атрибутів HTML, які викликають оцінку JavaScript.
Детальніше читайте тут: