Защита NodeJS CSRF с включенными Express, GraphQL и CORS

Я создаю веб-сервис, очень похожий на shopify, но использую только JS. Nodejs Express для API с включенными GraphQl и Cors. VueJS для внешнего интерфейса. Моя проверка подлинности выполняется с помощью JWT. Но у меня есть такие вещи, как анонимный заказ, поэтому мне нужна защита CSRF. Дело в том, что мой API - это не роутер. Мой маршрутизатор находится во внешнем интерфейсе, и я получаю только нужные мне данные через Graphql через вызовы Axios к API. Я взглянул на модуль csurf и попробовал его, но в настоящее время я получаю токен CSRF для внешнего интерфейса с помощью конечной точки / getCSRFToken в API, который я прочитал, не является хорошей практикой, а другое - он включен чтобы получить доступ ко всем из-за включенного CORS.

Это основной источник информации, который у меня есть: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

Я не знаю, как точно настроить защиту CSRF, не имея маршрута API для получения токена CSRF и отправки его в виде файла cookie через ответ и, как правило, сделать все это безопасным с помощью лучших практик.

Я также думал об ограничении доступа к API только для доменов магазинов, которые есть в системе, но не сейчас, если это тоже будет хорошо.

Любые предложения приветствуются

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
894
1

Ответы 1

Вы можете сгенерировать клиентскую сторону cookie (используя window.crypto), затем попросить JS прочитать его и отправить в заголовке, сервер просто должен проверить, что они совпадают. Но это уязвимо из-за того, что файл cookie не является HttpOnly (потому что ваш JS должен его прочитать!). По этой причине этот метод не лучший, но он лучше, чем ничего.

Это также не мешает пользователям отправлять запросы от curl и тому подобное, если они выясняют, что им нужно только предоставить соответствующий файл cookie и заголовок, но они по-прежнему не могут отправлять запросы от имени других пользователей, если у них нет учетных данных для авторизации целевых пользователей.


На самом деле нет ничего плохого в том, чтобы иметь маршрут API, который генерирует токен для каждого запроса, хотя это приводит к удвоению плотности запросов (вам нужен новый токен для каждого запроса!). Причина этого в том, что злоумышленник не может прочитать ответ с внешнего сайта (CORS предотвратит это). Тогда вы не будете уязвимы для использования файлов cookie, поскольку вы вообще никогда не храните файлы cookie.

Редактировать: Я вижу, вы намекаете на то, что CORS * включен для этой конечной точки, чтобы она была общедоступной. Если ваш API действительно общедоступен, вам, вероятно, лучше будет использовать аутентификацию OAuth2 / JWT, так как CSRF становится неактуальным, поскольку аутентификация происходит не из файлов cookie.

Попытка сохранить значение в нескольких запросах сталкивается с трудностями с функцией истории, поэтому рекомендуется либо использовать токен для каждого запроса, либо ...

Вы также можете сохранить файл cookie из запроса getCsrfToken() и оставить его действительным в течение некоторого времени, но сделать его HttpOnly, поскольку он был выпущен API, API будет отвечать за получение действительного токена CSRF.

Проблема с обоими из вышеперечисленных заключается в том, что если вам нужна настоящая анонимность, вы не можете привязать эти токены к конкретному пользователю, чтобы один пользователь мог избежать проверок CSRF от имени другого, используя свой собственный токен CSRF!

Если вы можете придумать какой-то способ обойти это, сохраняя при этом анонимность, тогда сервер может проверять действительность токенов, которые он получает, так что один пользователь не может использовать свой токен от имени другого.


Ваша последняя идея (при условии, что вы хотите настоящую анонимность), вероятно, лучшая. При условии, что пользовательский агент заслуживает доверия, заголовки referer и Origin не могут быть изменены, поэтому, если вы счастливы заблокировать свой API только для доменов, на которых работает ваш JS, тогда выполнение проверки referer / Origin на стороне сервера не будет быть легко обойденным злоумышленником. Это не лучшая практика, но практически эффективна.

Опять же, запросы curl и тому подобное могут быть отправлены свободно, но они могут быть отправлены только от имени другого пользователя, если у злоумышленника есть учетные данные пользователя для авторизации.


Последнее, что следует отметить, это то, что CSRF является альтернативным вектором атаки XSS, но если у вас есть уязвимости XSS, защита CSRF обычно устаревает, поэтому убедитесь, что вы сначала защищаете XSS, прежде чем внедрять защиту CSRF.

В настоящее время я использую аутентификацию JWT, но при входе в систему я отправляю его на клиентский сайт как 2 файла cookie. Один для части подписи jwt, которая защищена, и одна из полезных данных для клиентской стороны, чтобы прочитать и получить от нее пользователя. Оба являются httpOnly и sameSite. Но я не понимаю, какое отношение это имеет к защите csrf, поскольку у меня есть анонимная проверка, для которой мне все еще нужна защита csrf, пока я не аутентифицирован. И не могли бы вы подробнее рассказать о OAuth2 / JWT и о том, как он не использует файлы cookie? Я имею в виду, как клиентская сторона знает, что я вошел в систему?

Peter 27.07.2018 13:06

Что мне интересно, это нормально, если у меня есть маршрут в API / getCSRFToken, чтобы получить токен CSRF для страницы, которую я собираюсь загрузить на стороне клиента, и если нет, как мне получить токен на стороне клиента

Peter 27.07.2018 13:26

Вы можете хранить токены в локальном хранилище вместо файлов cookie, а затем отправлять их по запросу. Если другой сайт пытается выполнить CSRF-запрос, у него просто нет токенов, и они тоже не могут их получить (где, как и в случае с файлами cookie, браузер отправит их), вы должны убедиться, что они уничтожены, признаны недействительными или зашифрованы, если вы храните их таким образом.

starlight54 27.07.2018 14:10

Что касается вашей действительно неаутентифицированной / анонимной конечной точки, вам просто нужно будет изолировать ее от своих доменов (вариант 3), если вы не готовы создать токен, который может реально использоваться только запрашивающим пользователем (это сложно, поскольку предположительно информация например, пользовательский агент / IP-адрес пользователя также доступен злоумышленнику)

starlight54 27.07.2018 14:13

Об использовании локального хранилища ... Я читал несколько статей, и они говорят, что использовать его для хранения аутентификационной информации не рекомендуется, так как это небезопасно и т. д. rdegges.com/2018/please-stop-using-local-storage

Peter 27.07.2018 16:44

Нет никаких сомнений в том, что HttpOnly и SameSite Auth и файлы cookie CSRF являются лучшей отраслевой практикой. Проблема с SameSite заключается в том, что Microsoft только что догнала и внедрила его, поэтому любой из ваших пользователей, не использующих последнюю версию Windows 10 с использованием браузера MS, скорее всего, станет уязвимым. Я бы сказал, что самая большая проблема для локального хранилища - это закрытие браузера, поэтому я говорю, что если вы его используете, токены должны быть как зашифрованными, так и недолговечными. Я согласен, что это делает их более уязвимыми для XSS, но именно в этом и сияют файлы cookie HttpOnly.

starlight54 27.07.2018 17:12

Основная проблема здесь заключается в том, что для вашей анонимной конечной точки будет сложно предложить HttpOnly, SameSite Cookie, которыми нельзя злоупотреблять без деанонимизации проверки, если вы придумаете какой-то способ сделать это, тогда это будет идеальный.

starlight54 27.07.2018 17:14

Другие вопросы по теме