Уязвимы ли веб-сервисы JSON для атак CSRF?

82

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

Уязвима ли веб-служба для атаки CSRF, если верно следующее?

  1. Любой POSTзапрос без объекта JSON верхнего уровня, например, {"foo":"bar"}будет отклонен с 400. Например, POSTзапрос с содержимым 42будет таким образом отклонен.

  2. Любой POSTзапрос с типом содержимого, отличным от типа, application/jsonбудет отклонен с 400. Например, POSTзапрос с типом содержимого application/x-www-form-urlencodedбудет таким образом отклонен.

  3. Все запросы GET будут безопасными и, следовательно, не будут изменять какие-либо данные на стороне сервера.

  4. Клиенты аутентифицируются с помощью файла cookie сеанса, который веб-служба предоставляет им после того, как они предоставят правильную пару имени пользователя и пароля через POST с данными JSON, например {"username":"user@example.com", "password":"my password"}.

Вспомогательные вопросы: Аре PUTи DELETEзапросы всегда уязвимы для CSRF? Я спрашиваю, потому что кажется, что большинство (всех?) Браузеров запрещают эти методы в формах HTML.

РЕДАКТИРОВАТЬ: добавлен пункт №4.

РЕДАКТИРОВАТЬ: Пока много хороших комментариев и ответов, но никто не предлагал конкретную CSRF-атаку, для которой этот веб-сервис уязвим.

djsmith
источник
токенизируйте свои запросы с помощью парных значений сеанса и файлов cookie, дезинфицируйте любые директивы, которые вы запускаете через отправленный JSON, добавляйте соль для дополнительного вкуса
Брандт Соловидж
Я не думаю, что здесь достаточно информации, чтобы дать хороший ответ. Какой метод аутентификации вы используете? Кто являются предполагаемыми потребителями веб-службы (т.
Е.
1
Все ваши текущие проверки совершенно разумны и ограничивают вашу поверхность атаки, но на самом деле они не касаются ничего общего с уязвимостью CSRF.
Cheekysoft
2
@ DavidBalažic Какой вектор? Если вы говорите об AJAX, политики одного происхождения предотвратят это.
djsmith

Ответы:

73

Ковка произвольных запросов CSRF с типами произвольной медиа эффективно возможно только с XHR, так как метод формы ограничивается получить и POST и А тело сообщения POST формы имеют также ограничиваются три форматов application/x-www-form-urlencoded, multipart/form-dataиtext/plain . Однако с кодировкой данных формы по- text/plainпрежнему можно подделывать запросы, содержащие действительные данные JSON .

Таким образом, единственная угроза исходит от атак CSRF на основе XHR. И они будут успешными только в том случае, если они из одного и того же происхождения, то есть в основном с вашего собственного сайта (например, XSS). Будьте осторожны, чтобы не ошибиться, отключив CORS (т.е. не установив Access-Control-Allow-Origin: *) в качестве защиты. CORS просто не дает клиентам прочитать ответ. Весь запрос по-прежнему отправляется и обрабатывается сервером.

Гамбо
источник
9
Как я прокомментировал ваш связанный ответ, я утверждаю, что text / plain действительно может использоваться для подделки JSON, если серверу не требуется application / json, с использованием методов, аналогичных pentestmonkey.net/blog/csrf-xml-post-request .
8
Этот ответ верен до сегодняшнего дня, но, вероятно, скоро он будет неправильным. W3C рассматривает возможность добавления enctype = "application / json" в стандарт HTML: darobin.github.io/formic/specs/json. Поэтому не полагайтесь на тип тела POST для обеспечения долговременной безопасности, используйте токен анти-CSRF.
LordOfThePigs
@LordOfThePigs Создание действительного JSON уже возможно с помощью text / plain .
Gumbo
@Gumbo правильно, но в настоящее время вы не можете установить enctype, application/jsonкоторый используется для предотвращения атак CSRF в этом ответе. Предлагаемый стандарт позволит вам установить enctype равным application/json, что приведет к отмене проверок типа контента, описанных в ответе, и откроет приложение для CSRF.
LordOfThePigs
10
Похоже, драфт предотвращает эту атаку. В разделе 5 указано, что application/jsonсообщения формы должны соответствовать одной и той же политике происхождения, что означает, что атака не сильнее XHR.
James_pic
3

Да, это возможно. Вы можете настроить сервер злоумышленника, который будет отправлять 307 редирект на целевой сервер на машину жертвы. Вам необходимо использовать flash для отправки POST вместо использования формы.

Ссылка: https://bugzilla.mozilla.org/show_bug.cgi?id=1436241

Он также работает в Chrome.

Тимоти Люн
источник
1

С помощью Ajax можно выполнять CSRF на сервисах Restful на основе JSON. Я тестировал это в приложении (используя как Chrome, так и Firefox). Вы должны изменить contentType на text / plain и dataType на JSON, чтобы избежать предварительного запроса. Затем вы можете отправить запрос, но для отправки данных сеанса вам необходимо установить флаг withCredentials в вашем запросе ajax. Я обсуждаю это более подробно здесь (ссылки включены):

http://wsecblog.blogspot.be/2016/03/csrf-with-json-post-via-ajax.html

Филип Вэйтенс
источник
В этом нет необходимости. Если сервер читает запросы с открытым текстом как JSON, формы, закодированной как открытый текст, достаточно, чтобы подделать такой запрос, как упоминал Гамбо. Серверы API должны просто отклонять запросы с открытым текстом.
Франклин Ю
-1

У меня есть некоторые сомнения относительно пункта 3. Хотя его можно считать безопасным, поскольку он не изменяет данные на стороне сервера, данные все же можно прочитать, и существует риск их кражи.

http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx/

пантео
источник
1
Это работает, только если объект верхнего уровня, возвращаемый API, является массивом JSON, поскольку Javascript позволяет переопределить конструктор Array. Объект верхнего уровня безопасен. Подробнее на flask.pocoo.org/docs/0.10/security/#json-security .
btubbs
По словам самого автора, « я не думаю, что в каких-либо современных браузерах больше есть этот недостаток ».
Франклин Ю
-6

Уязвима ли веб-служба для атаки CSRF, если верно следующее?

Да. Это все еще HTTP.

Уязвимы ли запросы PUT и DELETE для CSRF?

да

кажется, что большинство (все?) браузеры запрещают эти методы в формах HTML

Вы думаете, что браузер - единственный способ сделать HTTP-запрос?

symcbean
источник
3
Тот факт, что служба использует HTTP, не делает ее уязвимой для CSRF. Можете ли вы определить реальный вектор атаки CSRF, для которого эта служба, как описано, уязвима? И, конечно, я не думаю, что браузер - единственный способ сделать HTTP-запрос, но браузер является наиболее распространенным (только?) Для пользователя, которого обманом заставляют сделать поддельный межсайтовый запрос, который они не сделали. ожидать.
djsmith
Другими словами, покажите мне конкретный вектор атаки CSRF, который использует PUT, чтобы обманом заставить пользователя отправить запрос PUT в мою веб-службу (как описано). Я считаю, что это невозможно.
djsmith
@symcbean: Не могли бы вы разместить ссылки или иным образом защитить свой ответ? Я не голосовал за этот ответ, я бы хотел, чтобы вы сначала вмешались. Благодарю.
dotancohen 02
Google снова не работает? Не говоря уже о типах содержимого, старые версии Flash (более поздние версии flash имеют кроссдомиальную модель управления, но она отличается от HTML5) - как насчет контрабанды jar - pseudo-flaw.net/content/web-browsers/corrupted -jars (Java выполняется в активном контексте, но может вызывать javascript в пассивном контексте). Затем есть атаки повторного связывания DNS и атаки MITM
symcbean
Плагины браузера могут читать ваш файл cookie CSRF и отправлять любой заголовок, который они хотят, поэтому даже стандартные механизмы принудительного применения CSRF уязвимы для вредоносного плагина браузера.
djsmith