Я создаю веб-сервис, очень похожий на 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 только для доменов магазинов, которые есть в системе, но не сейчас, если это тоже будет хорошо.
Любые предложения приветствуются



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете сгенерировать клиентскую сторону 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.
Что мне интересно, это нормально, если у меня есть маршрут в API / getCSRFToken, чтобы получить токен CSRF для страницы, которую я собираюсь загрузить на стороне клиента, и если нет, как мне получить токен на стороне клиента
Вы можете хранить токены в локальном хранилище вместо файлов cookie, а затем отправлять их по запросу. Если другой сайт пытается выполнить CSRF-запрос, у него просто нет токенов, и они тоже не могут их получить (где, как и в случае с файлами cookie, браузер отправит их), вы должны убедиться, что они уничтожены, признаны недействительными или зашифрованы, если вы храните их таким образом.
Что касается вашей действительно неаутентифицированной / анонимной конечной точки, вам просто нужно будет изолировать ее от своих доменов (вариант 3), если вы не готовы создать токен, который может реально использоваться только запрашивающим пользователем (это сложно, поскольку предположительно информация например, пользовательский агент / IP-адрес пользователя также доступен злоумышленнику)
Об использовании локального хранилища ... Я читал несколько статей, и они говорят, что использовать его для хранения аутентификационной информации не рекомендуется, так как это небезопасно и т. д. rdegges.com/2018/please-stop-using-local-storage
Нет никаких сомнений в том, что HttpOnly и SameSite Auth и файлы cookie CSRF являются лучшей отраслевой практикой. Проблема с SameSite заключается в том, что Microsoft только что догнала и внедрила его, поэтому любой из ваших пользователей, не использующих последнюю версию Windows 10 с использованием браузера MS, скорее всего, станет уязвимым. Я бы сказал, что самая большая проблема для локального хранилища - это закрытие браузера, поэтому я говорю, что если вы его используете, токены должны быть как зашифрованными, так и недолговечными. Я согласен, что это делает их более уязвимыми для XSS, но именно в этом и сияют файлы cookie HttpOnly.
Основная проблема здесь заключается в том, что для вашей анонимной конечной точки будет сложно предложить HttpOnly, SameSite Cookie, которыми нельзя злоупотреблять без деанонимизации проверки, если вы придумаете какой-то способ сделать это, тогда это будет идеальный.
В настоящее время я использую аутентификацию JWT, но при входе в систему я отправляю его на клиентский сайт как 2 файла cookie. Один для части подписи jwt, которая защищена, и одна из полезных данных для клиентской стороны, чтобы прочитать и получить от нее пользователя. Оба являются httpOnly и sameSite. Но я не понимаю, какое отношение это имеет к защите csrf, поскольку у меня есть анонимная проверка, для которой мне все еще нужна защита csrf, пока я не аутентифицирован. И не могли бы вы подробнее рассказать о OAuth2 / JWT и о том, как он не использует файлы cookie? Я имею в виду, как клиентская сторона знает, что я вошел в систему?