2009-05-13 21 views
29

Tengo una aplicación web que extrae datos de mi API JSON recién creada.¿Cómo restrinjo el acceso JSON?

Mis páginas HTML estáticas llaman dinámicamente a la API JSON a través de JavaScript desde la página HTML estática.

¿Cómo restrinjo el acceso a mi API JSON para que solo yo (mi sitio web) pueda llamar desde ella?

En caso de que ayude, mi API es algo así como: http://example.com/json/?var1=x&var2=y&var3=z ... que genera el JSON apropiado en función de la consulta.

Estoy usando PHP para generar mis resultados JSON ... ¿puede restringir el acceso a la API JSON ser tan simple como verificar $_SERVER['HTTP_REFERER'] para asegurar que la API solo se llame desde mi dominio y no un usuario remoto?

+0

Solo para aclarar, ¿está tratando de hacerlo para que solo su servidor pueda usar la API, o solo las personas que vean sitios web desde su servidor? –

+1

Mi api de JSON está en: http: //example.com/json? ... y solo quiero que mi sitio web http://example.com pueda recuperar los resultados de mi API de JSON. –

+0

Solo por curiosidad, ¿por qué estás tratando de hacer esto? Es un poco contrario al grano de la web, por lo que sería bueno saber el razonamiento detrás del requisito. – Sam

Respuesta

4

Cualquier solución aquí va a ser imperfecta si sus páginas estáticas que usan la API necesitan estar en Internet público. Ya que necesita poder hacer que el navegador del cliente envíe la solicitud y que se la respete, es posible que casi cualquier persona vea exactamente cómo está formando esa URL.

Puede hacer que la aplicación detrás de su API compruebe la referencia http, pero eso es fácil de falsificar si alguien quiere.

Si no es un requisito que las páginas sean estáticas, podría intentar algo donde tenga una "clave" efímera generada por la API e incluida en la respuesta HTML de la primera página que se transfiere como una parámetro de vuelta a la API. Esto agregaría sobrecarga a su API, ya que tendría que tener el servidor en ese extremo para mantener una lista de "claves" que son válidas, por cuánto tiempo son válidas, etc.

Entonces, puede tomar algunas medidas lo cual no costará mucho pero no es difícil moverse si alguien realmente quiere, o puede pasar más tiempo para hacerlo un poco más difícil, pero no hay una manera perfecta de hacerlo si su API tiene que ser públicamente accesible.

+0

Esta es probablemente la solución más elegante, pero estoy de acuerdo en que es solo una solución alternativa y no una solución real (no la hay). –

+0

Entonces, lo que estás diciendo es que ... si revisé el 'HTTP_REFERER', eso al menos proporciona *** una *** garantía limitada de que solo mi sitio web está usando mi api JSON. Pero, una vez más, el 'HTTP_REFERER' puede ser fácilmente falsificado. –

+0

JamesZ - correcto. –

4

La respuesta breve es: cualquier persona que pueda acceder a las páginas de su sitio web también podrá acceder a su API.

Puede intentar dificultar el uso de su API cifrándola de varias maneras, pero como deberá incluir código JavaScript para descifrar el resultado de su API, solo se va a configurar para una carrera armamentista con cualquiera que decida que quiere usar su API por otros medios. Incluso si usa claves de corta vida, un "atacante" determinado siempre podría raspar su HTML (junto con la clave actual) justo antes de usar la API.

Si todo lo que quiere hacer es evitar que otros sitios web utilicen su API en sus páginas web, entonces podría usar encabezados Referrer pero no todos los navegadores envían Referrers (¡y algunos proxies también los quitan!). Esto significa que le gustaría permitir que todas las solicitudes no tengan una referencia, y esto solo le daría protección parcial. Además, los Referrers se pueden falsificar fácilmente, por lo que si algún otro sitio web realmente desea utilizar su API, ellos siempre pueden simular un navegador y acceder a su API desde sus servidores.

+1

No quiero cifrarlo, simplemente quiero restringir "quién" puede llamar a mi api JSON. La única persona a la que quiero llamar API es mi propio servidor web y no usuarios remotos. –

+0

Sí, de eso se trata el último párrafo de mi respuesta. Podría intentar usar el referente, pero puede ser fácilmente falsificado. –

18

El método habitual para restringir el acceso a su dominio es anteponer el contenido a algo que se ejecuta infinitamente.

Por ejemplo:

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

Así que cuando usted lo trae esto a través de XMLHttpRequest o cualquier otro método que se limita exclusivamente a su dominio, usted sabe que usted necesita para analizar el bucle infinito. Pero si se trae a través del nodo script:

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

Se fallará porque el guión nunca va a llegar más allá de la primera declaración.

+1

decir que? ¿Tu recomendación es crear un ciclo infinito?O me falta algo por completo aquí o estás tirando de mi pierna. –

+16

Excepto que cualquiera todavía puede llamarlo desde el código del lado del servidor sin ninguna molestia y simplemente quitar los bucles. –

+4

Sí, JameZ, eso es correcto. Un bucle infinito antepuesto al JSON evitará que su JSON se cargue en los nodos de script. Sí, no impedirá el acceso del servidor al servidor. Esta no es una solución de reparación. Es solo otra capa de seguridad. Evitará que sus datos se carguen en el lado del cliente utilizando el nodo de script. – fearphage

17

Creo que es posible que esté malinterpretando la parte donde se inicia la solicitud JSON desde el navegador del usuario en lugar de desde su propio servidor. La página HTML estática se entrega al navegador del usuario, luego da la vuelta y ejecuta el código JavaScript en la página. Este código abre una nueva conexión a su servidor para obtener los datos JSON. Desde el punto de vista de su script PHP, la solicitud JSON proviene de algún lugar del mundo exterior.

Dado el mecanismo anterior, no hay mucho que pueda hacer para evitar que nadie llame a la API JSON fuera del contexto de su página HTML.

+0

Si ese es el caso, ¿cómo proyectan las personas su api "RESTful"? ¿O estas API son públicas? –

+1

Generalmente, son API públicas. Dependiendo del sitio web, pueden o no estar documentados para el consumo público, pero todos deben ser construidos con miras a la solidez ante usuarios maliciosos (o simplemente indeseables). –

+0

Entonces, ¿cómo impide la gente que los usuarios envíen una consulta REST que simplemente vuelque todos los datos de la base de datos de las aplicaciones web? –

5

En mi opinión, no se puede restringir el acceso, solo hacerlo más difícil. Es un poco como restricción de acceso por oscuridad. Las referencias pueden falsificarse fácilmente, e incluso con la clave efímera, una secuencia de comandos puede obtener las respuestas actualizando constantemente la clave.

Entonces, ¿qué puede que hacemos?

Identificar la debilidad aquí:

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

El atacante puede ahora solicitar fácilmente toda la información del usuario de 1 a 1.000.000 en un bucle. El punto débil de las identificaciones auto_increment es su linealidad y que son fáciles de adivinar.

Solución: utilice identificadores únicos no numéricos para sus datos.

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

No puede recorrer más de esos. Es cierto que aún puede analizar las páginas HTML para las claves de todo tipo de claves, pero este tipo de ataque es un problema diferente (y más fácil de evitar).

Desventaja: Por supuesto, no puede usar este método para restringir las consultas que no dependen de la clave, p. Ej. buscar.

0

Lo siento, tal vez estoy equivocado pero ... ¿se puede hacer usando HTTPS?

Usted puede tener su API accesible a través de http s (?):? //example.com/json/ var1 = x & var2 = y, por lo tanto consumidor sólo autenticado puede obtener sus datos ...

+5

SSL no garantiza la identidad, solo evita que terceros vean tus datos mientras está en tránsito entre el navegador y el servidor. – RQDQ

0

¿Está o puede usar una autenticación basada en cookies? Mi experiencia se basa en la autenticación de formularios ASP.NET, pero el mismo enfoque debería ser viable con PHP con un pequeño código.

La idea básica es que, cuando el usuario se autentica a través de la aplicación web, se devuelve al navegador del cliente una cookie que tiene un valor encriptado. La api json luego usaría esa cookie para validar la identidad de la persona que llama.

Este enfoque obviamente requiere el uso de cookies, por lo que puede o no ser un problema para usted.

0

Lo sentimos, no hay DRM en la web :-)

No se puede tratar HTML como un cliente de confianza. Es una secuencia de comandos de texto sin formato interpretada en las computadoras de otras personas como mejor le parezca. Cualquier cosa que permita su "propio" código de JavaScript, ¿permite a alguien? Ni siquiera puedes definir cuánto tiempo es "tuyo" con Greasemonkey y Firebug en estado salvaje.

Debe duplicar todas las restricciones de control de acceso y lógica de negocios en el servidor como si nada estuviera presente en su cliente de JavaScript.

Incluya el servicio en su SSO, restrinja las URL a las que tiene acceso cada usuario, diseñe el mantenimiento del servicio como cliente, no su código JavaScript de buen comportamiento.

+0

¿Ah, y cuando las personas comienzan a usar su servicio de maneras que su HTML no permite? ¡Toma el consejo de desarrollo de negocios gratuito y sigue con él! – Szocske

Cuestiones relacionadas