Почему бы не использовать идентификатор сессии в качестве токена XSRF? - PullRequest
15 голосов
/ 06 августа 2011

Почему 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 возвращает идентификатор сеанса): (Воспроизведение / рамки / 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 в прошлом, когда они его использовали.

Ответы [ 3 ]

20 голосов
/ 24 августа 2014

Первое, что нужно сказать, это то, что вы можете повторно использовать идентификатор сеанса в качестве токена CSRF, поскольку он надежно защитит вас от CSRF и не создаст никаких серьезных брешей в безопасности.Однако, по несколько веским причинам, OWASP раньше явно рекомендовал против него .(Теперь они вообще не рассматривают вопрос.)

Аргумент против повторного использования идентификатора сеанса в качестве токена CSRF можно обобщить следующим образом (ключевые моменты выделены жирным шрифтом, с обоснованием ниже):

  1. Идентификатор сеанса, полученный злоумышленником, как правило, является более серьезным нарушением безопасности, чем токен CSRF, полученный злоумышленником.

    Все, что получает злоумышленникиз-за наличия токена CSRF (при условии, что некоторая другая защищенная часть информации, например идентификатор сеанса, не была повторно использована в качестве токена CSRF), является возможность выполнять атаки CSRF.Это дает им два огромных ограничения, которых у них не было бы, если бы они на самом деле приобрели идентификатор сеанса:

    • Им по-прежнему необходимо заманить пользователя с соответствующим токеном сеанса на страницу атаки (или прочитать его).электронное письмо с атакой или просмотр рекламного объявления в iframe и т. д.), чтобы использовать маркер CSRF любым способом.С идентификатором сеанса им просто нужно было бы поместить его в свой браузер и затем использовать веб-сайт, как если бы он был этим пользователем.
    • Хотя они могут отправлять запросы с использованием учетных данных пользователя, Одинаковая политика происхождения по-прежнему запрещает им просматривать ответы на эти запросы.На практике это может (или не может, в зависимости от структуры API, которое вы защищаете, и изобретательности злоумышленника) означать, что хотя злоумышленник может выполнять действия от имени пользователя, он не может получитьконфиденциальная информация , которую пользователь имеет право просматривать.(Какая из них вас больше интересует, зависит от контекста - можно предположить, что злоумышленник предпочитает забрать содержимое вашего банковского счета, просто зная, сколько это стоит, но что они также скорее знают вашу медицинскую историю, чем вандализируютит.)

  2. Токен CSRF потенциально легче получить злоумышленнику, чем идентификатор сеанса

    • Атаки XSS могут позволить злоумышленнику получить токен CSRF, поскольку обычной практикой является его вставка в DOM (например, в качестве значения элемента <input> в файлах cookie <form>.с другой стороны, может храниться в секрете даже перед лицом успешной атаки XSS с использованием флага HttpOnly , требующего от злоумышленника дополнительной предварительной работы для полезного использования уязвимости XSS.
    • Еслитокен CSRF отправляется обратно на сервер в качестве параметра запроса, а не настраиваемого заголовка HTTP (гарантированно будет при включении его в обычный HTML <form> отправляет), тогда журналы доступа веб-сервера обычно регистрируют токен CSRF в запросах GET (как часть URL).Таким образом, злоумышленник, которому удается просмотреть журнал доступа, сможет получить много токенов CSRF.
    • Страницы или сценарии, в которые запечен токен CSRF, могут быть кэшированы в браузере пользователя, что позволяет злоумышленнику получить их изкэш (возможно, релевантный после того, как пользователь, например, использовал общедоступный компьютер в библиотеке или интернет-кафе, а затем либо очистил их куки-файлы, но не их кэш, либо использовал кнопку «Выйти», которая удаляет их куки-файл сеанса избраузер без признания его недействительным на стороне сервера).

  3. Но если вы повторно используете идентификатор сеанса в качестве токена CSRF, то любая атака, которая позволяет им автоматически получить токен CSRFтакже дает им идентификатор сеанса.

  4. Поэтому не следует повторно использовать маркер CSRF в качестве идентификатора сеанса, поскольку это делает идентификатор сеанса более уязвимым.

Если честно, я как бы расцениваю все вышесказанное как скорее теоретическую проблему, чем практическую. Слабым местом в аргументе является пункт 2; единственные реалистичные уязвимости, о которых я могу подумать, которые могут быть использованы для получения токенов CSRF, но не для получения файлов cookie сеанса, все еще являются серьезными уязвимостями. Если у вас есть дыра в XSS на вашем сайте, или у злоумышленника есть доступ к вашим чокнутым серверным журналам , скорее всего, вы все равно трахаетесь. И в большинстве библиотек и интернет-кафе, в которых я был, сотрудники не разбирались в безопасности, и было бы довольно просто установить незамеченным кейлоггер и просто собрать пароли - злоумышленнику не нужно было бы заходить в попытка подождать, пока люди используют компьютер, а затем скопировать содержимое их кэша браузера.

Однако, если ваши обстоятельства каким-то образом не затрудняют хранение дополнительного случайного токена для CSRF вместе со случайным идентификатором сеанса, почему бы просто не сделать это в любом случае для получения какого-либо скромного преимущества для безопасности, которое оно дает вам?

3 голосов
/ 07 августа 2011

Чистая CSRF-атака не имеет доступа к cookie-файлам браузера, поэтому, когда вы говорите «перехватчик сообщений», это будет возможно только в том случае, если они прослушивают пакеты (т. Е. Нет SSL, общедоступный wifi).* В зависимости от конфигурации Play Framework (я не знаком с ней, так что примите это как общий совет веб-приложения), файлы cookie сеанса и аутентификации почти наверняка будут помечены как HttpOnly , поэтому ониневозможно прочитать с клиента через XSS.

В конечном счете, идея использования шаблона токена синхронизатора для защиты от XSRF заключается в использовании уникального значения (предпочтительно криптографически стойкого), известного только серверу и клиенту.и уникальным для этой сессии.Исходя из этой цели, Play Framework, похоже, отлично справляется.

2 голосов
/ 07 августа 2011

Возможно, Play Framework не хочет использовать SID в HTML.Конечный пользователь, Боб, может загрузить веб-страницу, и если на этой веб-странице есть <form>, SID будет включен в загруженный HTML (если сам SID используется в качестве токена XSRF).Если Боб затем отправит по электронной почте свою загруженную страницу Мэллори, Мэллори найдет SID и сможет выдать себя за Боба??

(Еще одна незначительная причина не использовать SID: как я уже упоминал в своем обновлении, SID может просто небыть доступным. Возможно, оно генерируется как можно позже, чтобы сэкономить ресурсы ЦП.)

...