Почему 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
возвращает идентификатор сеанса):
(play / framework / src / play / mvc / Scope.java)
public String getAuthenticityToken() {
return Crypto.sign(getId());
}
Здесь Play проверяет, что
имеет действительный токен XSRF:
(play / framework / src / play / 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 со старой версии 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 в прошлом, когда использовали его.