Рекомендации по безопасности JSON?

Во время исследования проблемы JSON vs XML я столкнулся с этим вопросом. Теперь одна из причин предпочтения JSON была указана как простота преобразования в Javascript, а именно с eval(). Теперь это сразу показалось мне потенциально проблематичным с точки зрения безопасности.

Итак, я начал изучать аспекты безопасности JSON и в этом блоге о том, как JSON не так безопасен, как думают люди.. Эта часть торчала:

Обновление: Если вы делаете JSON 100% правильно, тогда у вас будет только объекты на верхнем уровне. Массивы, Строки, числа и т.д. завернуты. Объект JSON не будет работать to eval(), потому что JavaScript переводчик будет думать, что он смотрит на блок, а не объект. Эта имеет большое значение для защиты от эти атаки, однако все же лучше для защиты ваших защищенных данных с помощью не предсказуемые URL.

Хорошо, так что хорошее правило для начала: объекты JSON на верхнем уровне всегда должны быть объектами, а не массивами, числами или строками. Мне кажется хорошим правилом.

Есть ли что-нибудь еще или избегать, когда речь идет о безопасности JSON и AJAX?

В последней части приведенной цитаты упоминаются непредсказуемые URL-адреса. Кто-нибудь имеет больше информации об этом, особенно о том, как вы это делаете в PHP? Я гораздо более опытен в Java, чем PHP, и в Java это просто (в том, что вы можете сопоставить целый ряд URL-адресов с одним сервлетом), тогда как весь PHP, который я сделал, сопоставил один URL-адрес PHP script.

Кроме того, как именно вы используете непредсказуемые URL-адреса для повышения безопасности?

Ответ 1

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

Когда люди говорят об уникальных URL-адресах, они обычно НЕ означают http://yourbank.com/json-api/your-name/big-long-key-unique-to-you/statement. Вместо этого, более распространено, чтобы сделать что-то еще о уникальном запросе; а именно значение в сообщении FORM или параметр URL.

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

Объект array/object - это новость для меня:

Script -Tags: злоумышленник может вставлять тег script, указывающий на удаленный сервер и браузер будет эффективно eval() ответ для вас, однако это отбрасывает ответ, и поскольку JSON - это ответ, вы в безопасности.

В этом случае ваш сайт не должен использовать JSON для уязвимости. Но да, если злоумышленник может вставить случайный HTML на ваш сайт, вы будете тосты.

Ответ 2

Существует ряд атак безопасности для JSON, особенно XSRF.

Уязвимость возникает, когда веб-служба использует файлы cookie для аутентификации и отвечает массивом JSON, содержащим конфиденциальные данные в ответ на запрос GET.

Если злоумышленник может обмануть пользователя, который зарегистрирован в службе, naive-webapp.com, для посещения своего сайта (или любого сайта, на котором установлен управляемый IFRAME, например, через встроенные объявления), тогда они могут вставить <script> с SRC на naive-webapp.com и потенциально украсть пользовательские данные. Это зависит от javascript quirk с конструктором JavaScript Array следующим образом:

 <script>
   // Overload the Array constructor so we can intercept data
   var stolenArrays = [];
   var RealArray = Array;
   Array = function () {
     var arr = RealArray.apply(arguments);
     stolenArrays.push(arr);
     return arr;
   }
 </script>
 <!-- even though the attacker can't access the cookies,
   - he can cause the browser to send them to naive-webapp.com -->
 <script src="//naive-webapp.com/..."></script>
 <script>
   // now stolenArrays contains any data from the parsed JSON
 </script>

EcmaScript 5 устранил запутанное поведение, которое вызвало [] поиск Array глобального объекта, и многие современные браузеры больше не подвержены этой атаке.

Кстати, Oil ошибается в отношении непредсказуемых URL-адресов. Криптографически безопасные случайные идентификаторы в URL-адресах - прекрасный способ защитить ресурсы. Безопасность, основанная на удостоверениях личности, не является панацеей, как предполагает Oil. См. http://waterken.sourceforge.net/ для примера схемы защищенного распределенного приложения на основе криптографически защищенных идентификаторов в URL-адресах, которая не требует понятия идентичности.

EDIT:

При рассмотрении JSON vs XML вы также должны знать о специфических для атак векторах XML.

XXE, XML Атаки внешних объектов, используют обработанный XML для доступа к файловой системе и сетевым ресурсам через брандмауэр.

<!DOCTYPE root 
[
<!ENTITY foo SYSTEM "file:///c:/winnt/win.ini">
]>
...
<in>&foo;</in>

Приложение вставляет вход (параметр "in", содержащий файл win.ini) в ответ веб-службы.

Ответ 3

он по-прежнему лучший для защиты ваших защищенных данных с помощью не предсказуемых URL-адресов.

Акцент мой. Какая ерунда! Это лучший, чтобы защитить ваши защищенные данные с помощью надлежащей проверки подлинности и, возможно, некоторого шифрования. Обмен JSON может по-прежнему использовать существующие методы аутентификации (например, сеансы через файлы cookie) и SSL.

Полагаясь на то, что кто-то не догадывается о URL-адресе (что они фактически говорят) будет разумным методом (и даже тогда, только когда-то), когда вы используете JSON для экспорта данных анонимному третьему лицу (например, веб-сервис). Одним из примеров является Google API различных веб-сервисов, в котором анонимные пользователи получают доступ к данным Google через другие веб-сайты. Они используют ключи доменного имени и API, чтобы убедиться, что веб-сайт "мужчина-в-середине" разрешен для предоставления данных Gooogle.

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


Изменить: чтобы продемонстрировать, что они означают, подумайте об этом. Представьте, что ваш банк предоставил JSON API для получения заявлений. Если бы я мог просто набрать http://yourbank.com/json-api/your-name/statement, вам, вероятно, было бы не очень приятно.

Они могут генерировать уникальную строку для вашей учетной записи, которая требовалась в любом запросе JSON, например: http://yourbank.com/json-api/your-name/big-long-key-unique-to-you/statement

У меня было бы гораздо меньше шансов угадать это. Но хотите ли вы, чтобы это был единственный буфер между вашими действительно защищенными данными и потенциальными ворами? Нет.