Подтвердить что ты не робот

Почему политики одного и того же происхождения недостаточно для предотвращения атак CSRF?

Прежде всего, я предполагаю, что бэкэнд управляет входами для предотвращения уязвимостей XSS.

В этот ответ @Les Hazlewood объясняет, как защитить JWT на стороне клиента.

Предполагая 100% TLS для всех сообщений - как во время, так и во все времена после входа в систему - аутентификация с именем пользователя/паролем через базовую аутентификация и получение JWT в обмене является допустимым вариантом использования. Это почти точно, как поток OAuth 2 ( "предоставление пароля" ) работает. [...]

Вы просто установите заголовок авторизации:

Authorization: Bearer <JWT value here>

Но, если говорить, если ваш клиент REST "не доверен" (например, JavaScript-браузер), я бы даже не сделал этого: любое значение в HTTP-ответ, доступный через JavaScript - в основном любой заголовок значение или значение тела ответа - можно обнюхивать и перехватывать через Атаки MITM XSS.

Лучше хранить значение JWT в файле cookie только для безопасного доступа, только для http (cookie config: setSecure (true), setHttpOnly (true)). Это гарантирует что браузер будет:

  • только когда-либо передают файл cookie через соединение TLS и
  • никогда не делает значение cookie доступным для кода JavaScript.

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

Самый простой способ сделать это - установить только защищенный (но не только HTTP) cookie со случайным значением, например. UUID.

Я не понимаю, почему нам нужен файл cookie со случайным значением, чтобы гарантировать, что внешние домены, инициирующие запросы на ваш сайт, не могут функционировать. Это не освобождает вас от политики одинакового происхождения?

От OWASP:

Проверка заголовка источника

Стандарт заголовка исходного HTTP был введен как метод защиты от CSRF и других междоменных атак. в отличие от referer, источник будет присутствовать в запросе HTTP, который возникает с URL-адреса HTTPS.

Если присутствует заголовок источника, его необходимо проверить для последовательность.

Я знаю, что общая рекомендация от OWASP сама по себе - это Synchronizer Token Pattern, но я не вижу, какие уязвимости остаются в ней:

  • TLS + JWT в защищенном httpOnly cookie + политика одинакового происхождения + отсутствие уязвимостей XSS.

ОБНОВЛЕНИЕ 1:  Политика одного и того же происхождения применяется только к XMLHTTPRequest, поэтому злой сайт может легко запросить форму POST-запроса, и это нарушит мою безопасность. Требуется явная проверка заголовка заголовка. Уравнение:

  • TLS + JWT в защищенном httpOnly cookie + Проверка заголовка заголовка + Нет уязвимостей XSS.
4b9b3361

Ответ 1

Резюме

У меня были непонятные концепции политики одинакового происхождения и CORS, которые @Bergi, @Neil McGuigan и @SilverlightFox помогли мне уточнить.

Прежде всего, что @Bergi говорит о

SOP не предотвращает отправку запросов. Это предотвращает страницу из доступ к результатам междоменных запросов.

- важное понятие. Я думал, что браузер не делает запрос на кросс-домен соответственно ограничениям SOP, но это справедливо только для того, что Monsur Hossain называет "непростыми запросами" в этот отличный учебник.

Запросы с кросс-началом представлены в двух вариантах:

  • простые запросы
  • "не очень простые запросы" (термин, который я только что составил)

Простые запросы - это запросы, отвечающие следующим критериям:

  • HTTP-метод сопоставляет (с учетом регистра) один из следующих:
    • ГОЛОВКА
    • GET
    • POST
  • Заголовки HTTP-заголовков (без учета регистра):
    • Принять
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type, но только если значение является одним из следующих:
      • применение/х-WWW-форм-urlencoded
      • многочастному/форм-данных
      • Текст/равнина

Таким образом, POST с приложением Content Type/x-www-form-urlencoded попадет на сервер (это означает уязвимость CSRF), но браузер не сделает доступными результаты этого запроса. POST с приложением Content Type/json является "непростым запросом", поэтому браузер сделает запрос prefligth, подобный этому

ОПЦИИ/конечная точка HTTP/1.1
Хост: https://server.com
Подключение: keep-alive
Метод доступа-контроля-запроса: POST
Происхождение: https://evilsite.com
Access-Control-Request-Headers: контент-тип
Принять: */*
Accept-Encoding: gzip, deflate, sdch
Accept-язык: es-ES, es; q = 0.8

Если сервер отвечает, например:

Access-Control-Allow-Origin: http://trustedsite.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: контент-тип
Content-Type: text/html; кодировка = UTF-8

браузер не сделает запрос вообще, потому что

XMLHttpRequest не может загрузить http://server.com/endpoint. Ответ на запрос предварительной проверки не проходит проверку контроля доступа: Заголовок "Access-Control-Allow-Origin" содержит недопустимое значение 'Trustedsite.com. Поэтому Origin 'evilsite.com' не допускается.

Поэтому я думаю, что Нил говорил об этом, когда он указывал, что:

Политика одинакового происхождения применяется только к чтению данных, а не к написав его.

Однако, с явным контролем заголовка источника, который я предложил Bergi, я думаю, достаточно в отношении этой проблемы.

Что касается моего ответа на Нейла, я не имел в виду, что этот ответ был единственным для всего моего вопроса, но он вспомнил мне еще одну важную проблему о SOP, и именно эта политика применима только к XMLHTTPRequest.

В заключение я считаю, что уравнение

  • TLS + JWT в защищенном httpOnly cookie + Проверка заголовка исходного кода + отсутствие уязвимостей XSS.

- хорошая альтернатива, если API находится в другом домене, таком как SilverlightFox. Если клиент находится в том же домене, что у клиента возникнут проблемы с запросами, которые не включают заголовок Origin. Снова из учебник по кругу:

Наличие заголовка Origin не обязательно означает, что запрос - это запрос с перекрестным происхождением. Хотя все запросы с кросс-началом будет содержать заголовок Origin, некоторые запросы с одним и тем же источником могут иметь один. Например, Firefox не включает заголовок Origin on запросы одного и того же происхождения. Но Chrome и Safari включают заголовок Origin при запросах POST/PUT/DELETE одного и того же происхождения (запросы GET того же происхождения будут не иметь заголовок Origin).

Silverlight указал этот на.

Единственный риск, который остается, заключается в том, что клиент может обмануть заголовок источника, чтобы он соответствовал разрешенному происхождению, поэтому ответ, который я искал, на самом деле был this

ОБНОВЛЕНИЕ: для тех, кто смотрит этот пост, у меня есть сомнения о том, нужен ли заголовок источника вообще с помощью JWT.

Уравнение будет:

  • TLS + JWT хранится в защищенном файле cookie + JWT в заголовке запроса + Нет уязвимостей XSS.

Кроме того, предыдущее уравнение имеет httpOnly cookie, но это не сработает, если вы получили клиент и сервер в разных доменах (например, сегодня много приложений SPA), потому что cookie не будет отправляться с каждым запросом на сервер. Поэтому вам нужно получить доступ к токену JWT, хранящемуся в файле cookie, и отправить его в заголовок.

Ответ 2

Почему политика одинакового происхождения недостаточно для предотвращения атак CSRF?

Потому что политика одного происхождения применяется только к чтению данных и не к записи.

Вы хотите избежать http://compromised.com от создания запроса, подобного этому (из браузера пользователя):

POST http://example.com/transfer-funds
fromAccountId:1
toAccountId:666

Законный запрос будет выглядеть так:

POST https://example.com/transfer-funds
fromAccountId: 1
toAccountId: 666
csrfToken: 249f3c20-649b-44de-9866-4ed72170d985

Вы делаете это, требуя значения (токен CSRF), который не может быть прочитан с внешнего сайта, то есть в заголовке ввода формы HTML или в заголовке ответа.

Что касается заголовка Origin, старые браузеры не поддерживают его, и у Flash были некоторые уязвимости, которые позволяют клиенту изменить его. В принципе, вы будете доверять Adobe, чтобы в будущем ничего не взорвать.

убедитесь, что у вас есть защита CSRF для каждого HTTP-запроса.

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

Ответ 3

Я просто хочу обобщить ответы.

  • Как упоминалось выше, SOP применяется только к XmlHttpRequests. Это означает, что браузеры спецификации должны отправлять заголовок ORIGIN вместе с запросами, которые были сделаны с помощью XmlHttpRequests.
  • Если вы проверите Chromium, отправьте ORIGIN при отправке формы. Однако это не означает, что другие браузеры это делают. На приведенном ниже рисунке показаны два почтовых запроса, сделанных в Firefox. Один из них сделан представляет форму, а второй - с помощью XHR. Оба запроса были сделаны от http://hack:3002/changePassword до http://bank:3001/chanePassword.
  • Браузеру разрешено не отправлять заголовок ORIGIN, если запрос был сделан из того же домена. Поэтому сервер должен проверять исходную политику только при установке заголовка источника.

Вывод: если вы используете файлы cookie и запрос приходит на сервер без заголовка ORIGIN, вы не можете отличить, было ли это сделано, отправив форму из другого домена или XHR в пределах того же домена. Вот почему вам нужна дополнительная проверка с помощью CSRF.

введите описание изображения здесь