Как ограничить доступ JSON?

У меня есть веб-приложение, которое извлекает данные из моего недавно созданного API JSON.

Мои статические HTML-страницы динамически вызывают JSON API через JavaScript со статической HTML-страницы.

Как ограничить доступ к моему API JSON, чтобы только я (мой веб-сайт) мог позвонить из него?

В случае, если это помогает, мой API-интерфейс похож на: http://example.com/json/?var1=x&var2=y&var3=z … который генерирует соответствующий JSON на основе запроса.

Я использую PHP для генерации моих результатов JSON … может ограничивать доступ к API JSON так же просто, как проверять $_SERVER['HTTP_REFERER'] чтобы гарантировать, что API вызывается только из моего домена, а не из удаленного пользователя ?

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

Например:

 while(1);{"json": "here"} // google uses this method for (;;);{"json": "here"} // facebook uses this method 

Поэтому, когда вы получаете это через XMLHttpRequest или любой другой метод, который ограничивается исключительно вашим доменом, вы знаете, что вам нужно разобрать бесконечный цикл. Но если он извлекается через узел скрипта:

 <script src="http://some.server/secret_api?..."></script> 

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

Я думаю, вы можете ошибаться в том, что запрос JSON инициируется из браузера пользователя, а не из вашего собственного сервера. Статическая страница HTML доставляется в браузер пользователя, затем она поворачивается и выполняет код Javascript на странице. Этот код открывает новое соединение с сервером для получения данных JSON. С точки зрения вашего PHP-скрипта запрос JSON поступает откуда-то из внешнего мира.

Учитывая вышеуказанный механизм, вы не можете сделать ничего, чтобы никто не мог вызвать JSON API вне контекста вашей HTML-страницы.

На мой взгляд, вы не можете ограничивать доступ, только усложняйте его. Это немного похоже на ограничение доступа от неясности. Ссылающиеся могут легко подделываться, и даже с помощью короткоживущего ключа скрипт может получать ответы, постоянно обновляя ключ.

Итак, что мы можем сделать?

Определите слабость здесь:

http://www.example.com/json/getUserInfo.php?id=443

Теперь злоумышленник может запросить всю информацию о пользователе от 1 до 1.000.000 в цикле. Слабой точкой идентификаторов auto_increment является их линейность и их легко угадать .

Решение: используйте нечисловые уникальные идентификаторы для ваших данных.

http://www.example.com/json/getUserInfo.php?userid=XijjP4ow

Вы не можете зацикливаться на них. Правда, вы все еще можете разобрать HTML-страницы для ключей для всех типов ключей, но этот тип атаки отличается (и более легко можно избежать).

Недостаток: конечно, вы не можете использовать этот метод для ограничения запросов, которые не зависят от ключа, например, для поиска.

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

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

Если для страниц не является статичным, вы можете попробовать что-то, где у вас есть недолговечный «ключ», сгенерированный API, и включенный в ответ HTML на первой странице, который передается как параметр обратно в API. Это добавило бы накладные расходы на ваш API, хотя, как вам нужно, чтобы сервер с этой целью поддерживал список «ключей», которые действительны, как долго они действительны и т. Д.

Таким образом, вы можете сделать несколько шагов, которые не будут стоить дорого, но не сложно обойтись, если кто-то действительно этого хочет, или вы можете потратить больше времени, чтобы сделать его немного сложнее, но нет идеального способа сделать это, если ваш API должен быть общедоступным.

Короткий ответ: любой, кто может получить доступ к страницам вашего сайта, также сможет получить доступ к вашему API.

Вы можете попытаться сделать использование вашего API более сложным, зашифровав его различными способами, но поскольку вам нужно будет включить JavaScript-код для дешифрования вывода вашего API, вы просто собираетесь настраивать себя на гонку вооружений с помощью любой, кто решает, что они хотят использовать ваш API с помощью других средств. Даже если вы используете краткосрочные ключи, определенный «атакующий» всегда может просто очистить ваш HTML (вместе с текущим ключом) непосредственно перед использованием API.

Если все, что вы хотите сделать, – это запретить другим веб-сайтам использовать ваш API на своих веб-страницах, тогда вы можете использовать заголовки Referrer, но имейте в виду, что не все браузеры отправляют Referrers (и некоторые прокси тоже стирают их!). Это означает, что вы хотите разрешить всем запросам отсутствие реферера, и это даст вам только частичную защиту. Кроме того, Referrers можно легко подделать, поэтому, если какой-либо другой сайт действительно хочет использовать ваш API, он всегда может просто обмануть браузер и получить доступ к вашему API со своих серверов.

Можете ли вы использовать аутентификацию на основе файлов cookie? Мой опыт основан на аутентификации форм ASP.NET, но тот же подход должен быть жизнеспособным с PHP с небольшим кодом.

Основная идея заключается в том, что когда пользователь аутентифицируется через веб-приложение, cookie с зашифрованным значением возвращается в браузер клиента. Затем json api будет использовать этот файл cookie для проверки личности вызывающего.

Этот подход явно требует использования файлов cookie, так что это может быть или не быть проблемой для вас.

Извините, может быть, я ошибаюсь, но … можно ли это сделать с помощью HTTPS?

Вы можете (?) Иметь ваш API доступный через http s : //example.com/json/? Var1 = x & var2 = y, таким образом, только аутентифицированный потребитель может получить ваши данные …

Извините, в Интернете нет DRM 🙂

Вы не можете рассматривать HTML как доверенный клиент. Это простой текстовый скрипт, который интерпретируется на компьютерах других людей по своему усмотрению. Независимо от того, что вы разрешите своим «собственным» кодом JavaScript, вы разрешаете кому-либо. Вы даже не можете определить, сколько времени это «ваше» с Greasemonkey и Firebug в дикой природе.

Вы должны дублировать все ограничения доступа и ограничения бизнес-логики на сервере, как если бы ни один из них не присутствовал в вашем JavaScript-клиенте.

Включите службу в свой SSO, ограничьте URL-адреса, к которым имеет доступ каждый пользователь, спроектируйте службу, поддерживающую wget, как клиент, а не ваш код JavaScript, который вы хорошо ведете.