Узел экспресс статический с CSRF - PullRequest
0 голосов
/ 23 сентября 2019

Я пытаюсь использовать csurf в nodejs, express и React Project.Мой csurf сейчас работает нормально, но я хочу еще раз проверить, правильно ли я это сделал.

Вот мой маршрутизатор nodejs и структура промежуточного ПО:

app.use(cookieParser());

app.use("/api/...") // routes that don't need csrf

app.use("/form/...",csrf({cookie:true})) // form path with csrf middleware

app.use(express.static("/img")) // image folder which doesn't need csrf

app.use(csrf({ cookie: true })); // enable csrf for the rest of the app 
app.all("*", function(req, res, next) {
  res.header("X-CSRF-Token", req.csrfToken()); // set csrf to header
  return next();
});

app.use(express.static("/SPA")); // frontend project

Текущее поведение:

  1. Когда я впервые захожу в свой веб-проект, у меня есть X-CSRF-Token: xxxxx и set-cookie: _csrf=yyyyy; Path=/ в моем response headers

  2. КогдаЯ обновляю свою страницу, в разделе request headers появляется Cookie: _csrf=yyyyy;.

  3. Когда я обновляю свою страницу, X-CSRF-Token меняется на другое значение.

  4. Только X-CSRF-Token значение, переданное через почтовый запрос, _csrf значение в файле cookie 403.

Вопрос:

A.Я считаю, что установка app.use(csrf({ cookie: true })) является избыточной, но когда я установил значение false или удалил часть app.all(...), приложение выбрасывает 403 / Internal Server Error.Как это исправить?

B.X-CSRF-Token меняется каждый раз, когда я обновляю свою страницу, это, очевидно, нормальное поведение, поскольку я помещаю его в заголовок, но не противоречит ли это цели csrf?Поскольку мой проект - SPA, меня это очень волнует?

Пожалуйста, укажите, было ли что-то не так с логикой / поведением?

Спасибо.

1 Ответ

0 голосов
/ 24 сентября 2019

Так как мой проект - SPA, действительно ли я так волнуюсь?

Если клиентское приложение (SPA или нет) отправляет некоторые данные в бэкэнд, и данные изменяют либо состояние бэкэнда, либопрямо или косвенно, например, посредством действия, выполняемого бэкэндом от имени клиента, существует уязвимость CSRF, и вам следует позаботиться о том, чтобы инфраструктура SPA, такая как Angular, не позаботилась о защите CSRF.Использование SPA ничего не меняет в отношении CSRF, это не помогает и ничего не облегчает.

С промежуточным программным обеспечением для парсера cookie промежуточное программное обеспечение csrf работает следующим образом:

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

  • Если файл cookie не найден, а входящий запрос мутирует, как POST (например, не GET, HEAD ...), тогда не удается выполнить его, например отправить 403 обратнос набором печенья.Если он не мутирует, как GET, тогда обработка завершается.

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

Чтобы убедиться, что эта проверка прошла успешно, вы несете ответственность за 2 шага:- по внутреннему вызову req.csrfToken(), чтобы получить этот второй фрагмент данных и сохранить в ответе.Вы решили сохранить его в HTTP-заголовке, это нормально.Но вы могли бы использовать любое имя заголовка.Или вы могли бы использовать тег <meta> в разделе <head>.- на клиенте возьмите второй фрагмент данных из указанного выше заголовка или тег <meta> в ответе бэкэнда и поместите его в запрос, который вы собираетесь отправить, предполагая, что запрос мутирует, например, POST, PUT,и т.д. Кроме того, вам нужно поместить его в одно из предопределенных мест в запросе, где промежуточное ПО csrf ищет по умолчанию.

Относительно вашего кода:1. Код клиента, отвечающий за второй шаг, отсутствует.2. На бэкэнд вызовите функцию csrf({options}) один раз и сохраните возвращаемое значение.Вы назвали это дважды.Возвращаемое значение, назовем его retValue, является сконфигурированным промежуточным программным обеспечением csrf, используйте его по мере необходимости:app.post(/<path>, retValue, ...req, res, next) => {...3. Что касается параметров, установите httpOnly: true.Дополнительно в производственном комплекте secure: true:

csrf({cookie: {
  httpOnly: true,
  secure: true
}})
...