Рекомендации по безопасности 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
У меня было бы гораздо меньше шансов угадать это. Но хотите ли вы, чтобы это был единственный буфер между вашими действительно защищенными данными и потенциальными ворами? Нет.