Столкновения токенов CSRF с несколькими вкладками

Я построил CSRF защита в моем приложении, просто генерируя случайный токен на загрузка страницы, ввод ее в сеанс, а затем привязка токена к <body> атрибут тег:

<body data-csrf-token="csrf_GeJf53caJD6Q5WzwAzfy">

затем при каждом действии формы или запросе ajax я просто хватаю токен из тега body и отправляю его вместе.

это отлично работает, за исключением огромной проблемы. Пользователи открывают несколько вкладок приложения, и я вижу знак столкновения. Например, пользователь загружает первую страницу и генерирует токен, затем они переключают вкладки, загружают другую страницу, которая генерирует новый токен. Наконец, они переключаются на первую страницу и отправляют действие формата. Это приводит к недопустимой ошибке токена CSRF.

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

просто генерируя один маркер при входе в систему правильный решение, а не генерировать новый токен при каждой загрузке страницы?

2 ответов


предполагая, что ваше приложение защищено SSL, то на самом деле нет никакого значения, созданного путем создания новых токенов при каждой загрузке страницы. Это не останавливает злоумышленника, который воспользовался уязвимостью XSS – у них все равно был бы доступ к только что сгенерированному токену.

помните, что защищает токен CSRF: вредоносная сторонняя страница слепо пытается опубликовать данные в вашем приложении в надежде, что пользователь вошел в систему. При такой атаке у нападающего никогда не будет доступа к токен CSRF, поэтому его изменение часто не приносит пользы.

Не тратьте время и ресурсы, отслеживая несколько токенов за сеанс. Просто сгенерируйте его в начале и все.


вы можете использовать один токен при входе в систему. Как указывает @Josh3736, это работает просто отлично.

Если вы действительно хотите иметь один токен на страницу, вы можете сохранить массив допустимых токенов в $_SESSION. Затем срок действия отдельных токенов истекает по мере их использования. Вы также можете по желанию истечь их после некоторого периода тайм-аута, но это имеет значение только в том случае, если тайм-аут короче тайм-аута сеанса. Но, опять же, чего вы на самом деле добиваетесь? Один токен отлично подходит для целей CSRF.