Почему Play Framework использует [подписанную версию идентификатора сеанса] в качестве Межсайтовая подделка запросов (XSRF / CSRF), а не сам идентификатор сеанса?
(Под токеном предотвращения XSRF я имею в виду магическое значение, которое должно быть включено в отправку формы, чтобы веб-приложение могло принять форму.)
Если есть перехватчик, он / она найдет и токен XSRF, и файл cookie SID (?).
Если есть эксплойт XSS, то вредоносный код JavaScript может читать как токен XSRF, так и cookie SID (?).
Тем не менее:
Злоумышленник не может создать действительный токен XSRF, учитывая SID, поскольку у него / нее нет секретного ключа, используемого при подписании SID для получения токена XSRF. - Но как могло случиться, что злоумышленник овладевает только SID, а не токеном XSRF? Это надумано?
Если SID отправляется в файле cookie только HTTP, то у злоумышленника не будет SID, даже если он обнаружит маркер XSRF, и, возможно, злоумышленнику действительно нужен SID? - Это надумано?
Фрагменты кода:
Здесь Play создает свой токен XSRF (getId
возвращает идентификатор сеанса):
(Воспроизведение / рамки / SRC / воспроизведение / MVC / Scope.java)
public String getAuthenticityToken() {
return Crypto.sign(getId());
}
Здесь Play проверяет, что <form>
имеет действительный токен XSRF:
(Воспроизведение / рамки / SRC / воспроизведение / MVC / Controller.java)
protected static void checkAuthenticity() {
if(Scope.Params.current().get("authenticityToken") == null ||
!Scope.Params.current().get("authenticityToken").equals(
Scope.Session.current().getAuthenticityToken())) {
forbidden("Bad authenticity token");
}
}
Обновление:
Play изменил способ генерации токенов XSRF, теперь SID больше не используется, вместо этого случайное значение подписывается и используется! (Я только что обновил свой клон репозитория Play Framework Git со старой версии Play 1.1 до новой версии 1.2. Возможно, мне следовало сделать это ... вчера, хм.)
public String getAuthenticityToken() {
if (!data.containsKey(AT_KEY)) {
data.put(AT_KEY, Crypto.sign(UUID.randomUUID().toString()));
}
return data.get(AT_KEY);
}
Ну, тогда почему они сделали это изменение?
Я нашел коммит:
[# 669] Исправить снова и применить к Flash и ошибкам
d6e5dc50ea11fa7ef626cbdf01631595cbdda54c
Из номера # 669 :
создавать сессию только в случае крайней необходимости
Сеансовый cookie создается при каждом запросе ресурса. play должен создавать cookie-файл сеанса, только если в сеансе действительно есть данные, которые нужно сохранить.
Таким образом, они используют случайное значение, а не SID, потому что SID, возможно, еще не был создан. Это причина не использовать производную SID в качестве токена XSRF. Но не разъясняет, почему они подписывали / хэшировали SID в прошлом, когда они его использовали.