Почему Play Framework использует [подписанную версию идентификатора сеанса] как Подделку запроса на межсайтовый сайт (XSRF/CSRF), а не сам идентификатор сеанса?
(с токеном предотвращения XSRF, я имею в виду магическое значение, которое должно быть включено в представление формы, чтобы webapp принимал форму.)
Если есть подслушивающее устройство, он все равно найдет токен 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 проверяет, что a <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");
}
}
Update:
Play изменил способ генерации токенов XSRF, теперь SID больше не используется, вместо этого используется случайное значение и используется! (Я только что обновил свою платформу Play Framework Git repo от старой версии версии 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);
}
Ну, тогда почему они сделали это изменение?
Я нашел commit:
[# 669] Исправить ошибку и применить к Flash и ошибкам, а также
d6e5dc50ea11fa7ef626cbdf01631595cbdda54c
Из журнала # 669:
создавать сеанс только в случае необходимости
Куки файлы сеанса создаются по каждому запросу ресурса. игра должна создавать только cookie сеанса, если в сеансе действительно хранятся данные.
Таким образом, они используют случайное значение, а не идентификатор SID, поскольку SID еще не был создан. Хорошо, что причина не использовать производную от SID в качестве токена XSRF. Но не поясняет, почему они подписали/хэшировали SID, в прошлом, когда они его использовали.