uber didi china php json api rest

php - didi - ¿Cómo restrinjo el acceso JSON?



didi china (8)

Tengo una aplicación web que extrae datos de mi API JSON recién creada.

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 allí?

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

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


¿Eres o puedes 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 una cookie que tiene un valor encriptado al navegador del cliente. 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.


Creo que es posible que esté malinterpretando la parte donde la solicitud JSON se inicia 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 alguien llame a la API JSON fuera del contexto de su página HTML.


Cualquier solución aquí 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 parámetro al 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.

Por lo tanto, puede tomar algunas medidas que no cuestan mucho, pero que no son difíciles de sortear 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 esto si su API tiene que ser públicamente accesible.


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

Entonces, cuando recuperas esto a través de XMLHttpRequest o cualquier otro método que esté restringido únicamente a tu dominio, sabes que necesitas analizar el ciclo infinito. Pero si se busca a través del nodo script:

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

Fallará porque el script nunca irá más allá de la primera declaración.


En mi opinión, no puedes 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é podemos hacer?

Identifica la debilidad aquí:

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

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

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

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

No puedes recorrer 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, por ejemplo, búsqueda.


La respuesta breve es: cualquiera 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, simplemente se preparará para una carrera armamentista con cualquier persona 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 tenga en cuenta que no todos los navegadores envían Referrers (¡y algunos proxies también los eliminan!). 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 remitentes se pueden falsificar fácilmente, por lo que si algún otro sitio web realmente desea utilizar su API, siempre pueden simular un navegador y acceder a su API desde sus servidores.


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

No 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 cada usuario tiene acceso, diseñe el servicio que mantiene wget como cliente, no su código JavaScript de buen comportamiento.


Lo siento, quizás estoy equivocado pero ... ¿se puede hacer usando HTTPS?

Puede (?) Tener su API accesible a través de http s : //example.com/json/? Var1 = x & var2 = y, por lo tanto, solo el consumidor autenticado puede obtener sus datos ...