Почему бы не использовать идентификатор сеанса в качестве токена XSRF?

Почему Play Framework использует [подписанную версию идентификатора сеанса] как подделку межсайтовых запросов (XSRF / CSRF) ) токен предотвращения, а не сам идентификатор сеанса?

(Под токеном предотвращения XSRF я имею в виду магическое значение, которое должно быть включено в отправку формы, чтобы веб-приложение приняло форму.)

Если есть перехватчик он / она все равно найдет и токен XSRF, и файл cookie SID (?).

Если есть эксплойт XSS, то вредоносный код JavaScript может прочитать как токен XSRF, так и файл cookie SID (?).

Однако:

  1. Злоумышленник не может создать действительный токен XSRF, учитывая SID, поскольку у него / нее нет секретного ключа, используемого при подписании SID для получения токена XSRF. - Но как могло случиться, что злоумышленник получает только SID, а не токен XSRF? Это надумано?

  2. Если 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 в прошлом, когда использовали его.

15
задан KajMagnus 7 August 2011 в 05:34
поделиться