Защита запросов HTTP (S) с использованием случайных заголовков

Я понимаю, что CSRF является серьезной проблемой безопасности для приложений на основе HTTP (S).

По внешнему виду, большинство фреймворков отправляют токен CSRF как часть тела запроса. Однако в моем случае это несколько неэлегантно по нескольким причинам; самое главное, я не хочу связываться с транспортным уровнем, который мог бы отправлять запросы POST во многих разных форматах, не обязательно все это JSON или x-www-form-urlencoded.

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

Есть ли какой-либо риск для безопасности (или другого рода)?

Ответ 1

Вы можете просто установить заголовок X-Requested-With, а затем проверить его на стороне сервера. Многие фреймворки, такие как JQuery, автоматически добавляются к запросам AJAX.

X-Requested-With является де-факто стандартом для указания того, что запрос выполняется через AJAX.

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

Следовательно, установка и проверка нестандартного заголовка является допустимым способом защиты от CSRF.

OWASP CSRF Предупреждающий чит-лист не упоминает об этом, однако он упоминает проверку заголовка Origin. Однако логика для этого не проста, так как многие браузеры не отправляют Origin для тех же запросов происхождения.

Также это работает только для запросов AJAX. При обычной форме POST невозможно добавить дополнительные заголовки. Кроме того, в прошлом были ошибки с плагинами, такими как Flash, которые позволяли устанавливать любой заголовок, позволяя злоумышленнику использовать Flash для запроса кросс-домена. Однако такие проблемы давно уже исправлены.

Если вы хотите использовать токен, а также часть стратегии защиты в глубину, вы можете адаптировать X-Requested-With, чтобы включить случайный токен, который вы затем проверяете. например X-Requested-With: XMLHttpRequest;0123456789ABCDEF.

Тогда токен может быть просто значением cookie, созданным только для целей предотвращения CSRF (сгенерировано с помощью криптографически безопасного алгоритма и энтропийного источника, конечно).

Ответ 2

Есть ли какой-либо риск для безопасности (или другого рода)?

Нет: как только вы сможете передать его клиенту и проверить на сервере - вы в порядке

Также, как часто я должен обновлять токен CSRF? Нужен ли мне новый для каждого запроса или каждые несколько запросов или один раз для посещения сайта и дня или...?

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