Проблемы с токеном CSRF с помощью Express

Я пытаюсь заставить CSRF-защиту работать с использованием csurf и express. Мое приложение использует Angular для интерфейса, поэтому я решил добавить это к моему приложению:

app.use(cookieParser('test secret'));
app.use(cookieSession({
 secret: 'test secret'
}));
app.use(csrf({
 cookie: {
 key: 'XSRF-TOKEN'
 }
}));

Однако, когда я пытаюсь выполнить POST-запросы, я получаю 403 ("недопустимый токен CSRF"). Насколько я могу судить, проблема заключается в csrf-tokens: в строке 44 expected переменная выглядит как qMnHLQGhivxECx5WtwuktDNA-snimacq30z-XNh2X-KTpdlkU6Og то время как secret и token переменные выглядят как qMnHLQGhivxECx5WtwuktDNA. Поскольку expected и token различны, возникает ошибка 403.

Я до сих пор пробовал следующее:

  • Настройка secure: false и/или signed: true в моих параметрах csurf
  • Убедитесь, что промежуточное программное обеспечение cookie-session и cookie-parser выполняется до csurf
  • Повторно установите все мои модули npm всякий случай
  • Кричать на моем компьютере

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

Кто-нибудь знает, как исправить эту проблему или что может быть причиной?

PS Кстати, я также заметил (возможно, не связанную) проблему: метод req.csrfToken() кажется, возвращает строки, значения которых полностью не связаны с expected значением в csrf-tokens или с строкой, хранящейся в файле cookie,

1 ответ

Существует ошибка/плохая реализация в отношении csurf lib. Файл cookie "XSRF-TOKEN" не хранит токен csrf, а секрет, который использует csurf для генерации токена csrf. Поэтому Угловая часть вашего приложения идентифицирует XSRF-TOKEN и правильно добавляет заголовок к HTTP-запросам, но промежуточное ПО csurf не распознает секрет как действительный токен CSRF. Чтобы устранить эту проблему, вы должны реализовать это как:

var cookieParser = require('cookie-parser');
var cookieSession = require('cookie-session');
app.use(cookieParser("secret"));
app.use(cookieSession({secret: "secret2"}));
app.use(csrf());
app.use(function (req, res, next) {
 res.cookie("XSRF-TOKEN",req.csrfToken());
 return next();
});

Req.csrfToken() будет генерировать токен csrf на основе сохраненного в этом случае секретного ключа в переменной req.session.csrfSecret, созданной промежуточным программным обеспечением csrf. Тогда это сработает.

EDIT: см. Эту проблему на GitHub

licensed under cc by-sa 3.0 with attribution.