Так как мой проект - 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
}})