Как я могу ограничить доступ JSON? - PullRequest
30 голосов
/ 13 мая 2009

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

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

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

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

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

Ответы [ 8 ]

18 голосов
/ 13 мая 2009

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

Например:

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

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

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

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

17 голосов
/ 13 мая 2009

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

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

5 голосов
/ 13 мая 2009

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

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

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

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-страницы для ключей для всех типов ключей, но этот тип атаки представляет собой другую (и более легко предотвращаемую) проблему.

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

4 голосов
/ 13 мая 2009

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

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

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

4 голосов
/ 13 мая 2009

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

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

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

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

0 голосов
/ 12 июля 2011

Извините, в сети нет DRM: -)

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

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

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

0 голосов
/ 01 июля 2010

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

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

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

0 голосов
/ 26 ноября 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...