2009-11-18 22 views
30

Voy a llamar al código php ajax de la siguiente manera:Restringir Acceso Directo a archivo llamado por el Ajax Función

ajaxRequest.open("GET", "func.php" + queryString, true); 

Ya que es una petición que nadie se lo puede ver simplemente examinando las cabeceras. Los datos que se pasan no son sensibles, pero podrían ser objeto de abuso, ya que también es trivial obtener los nombres de los parámetros.

¿Cómo evito el acceso directo al http://mysite/func.php pero a la vez le permito acceder a mi página ajax?

También he intentado con la solución posted here, pero no me funciona - siempre aparece el mensaje "No se puede acceder directamente".

+0

¿Así que básicamente quiere que su script esté accesible a través de AJAX pero no si escribo el URI? –

+0

sí, eso es exactamente – jriggs

+0

¿Hay algún motivo por el que no pueda utilizar el .htaccess descrito en el enlace que publicó? –

Respuesta

39

La mayoría de las solicitudes/marcos Ajax deben establecer este encabezado particular que puede usar para filtrar las solicitudes Ajax v Non-ajax. Lo utilizo para ayudar a determinar el tipo de respuesta (JSON/html) en un montón de proyectos:

if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest')) 
{ 
    // allow access.... 
} else { 
    // ignore.... 
} 

edición: Puede agregar esto por sí mismo en sus propias peticiones Ajax con lo siguiente en su código javascript:

var xhrobj = new XMLHttpRequest(); 
xhrobj.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 
+4

Aunque no es 100% efectivo (en el caso de que los encabezados sean falsificados), esta es una solución muy rápida y sencilla para permitir solo llamadas AJAX a la página. +1 –

+0

Ah ... este es el tipo de solución que esperaba obtener. Desafortunadamente, no estoy usando frameworks, solo javascript/ajax directamente. Cualquier tasa, la variable no está configurada con mi código, así que esto no funciona para mí. – jriggs

+0

Intento implementar eso con Google Maps llamando a un script php que devuelve datos XML. Sin embargo, GDownloadUrl ("", Función (datos) {var xml = GXml.parse (data); (...))} no me permite determinar el tipo de respuesta de esa manera en mi script PHP – richey

7

Mmm ... podría generar una contraseña de un solo uso en el inicio de sesión, que podría almacenar en _SESSION, y agregar un parámetro a su llamada ajax que lo retransmitiría (algo así como un captcha). Sería válido solo para esa sesión.

Esto lo protegería de los ataques automatizados, pero un humano que tenga acceso a su sitio aún podría hacerlo manualmente, pero podría ser la base para idear algo más complicado.

+0

Gracias - esto parece exagerado para mi escenario. La página que llamo solo está enviando un correo electrónico; el parámetro pasado es la dirección de correo electrónico. Realmente solo hice esta pregunta porque todavía soy bastante nuevo en ajax, y esto parece ser algo que puede ser un problema en futuras aplicaciones. – jriggs

0

En función de su descripción, supongo que está tratando de evitar el abuso desenfrenado absoluto, pero no necesita una solución sólida como una roca.

partir de eso, se recomienda usar las cookies:

Sólo setcookie() en la página que está utilizando el AJAX, y comprobar $_COOKIE para los valores correctos en func.php. Esto le dará una seguridad razonable de que cualquier persona que llame a func.php ha visitado su sitio recientemente.

Si quiere ser más elegante, puede establecer y verificar identificadores de sesión únicos (puede que ya lo haga) para asegurarse de que la cookie no se está forjando o abusando.

10

lo que uso es: sesiones de PHP + un hash que se envía cada vez que hago una solicitud. Este hash se genera usando algún algoritmo en el lado del servidor

4

Preguntaría por qué está tan convencido de que nadie debería poder visitar ese archivo directamente. Su primera acción debería ser suponer que las personas pueden visitar la página directamente y actuar en torno a esta eventualidad. Si aún está convencido de que desea cerrar el acceso a este archivo, entonces debe saber que no puede confiar en las variables $_SERVER ya que los orígenes de $_SERVER pueden ser difíciles de determinar y los valores de los encabezados pueden ser falsificados. En algunas pruebas, encontré esos encabezados ($_SERVER['HTTP_X_REQUESTED_WITH'] & $_SERVER['HTTP_X_REQUESTED_WITH']) para que no sean confiables también.

+0

Debido a que bots y hackers, scrappers, ddosers, Internet es un lugar desagradable, les das algo y la gente intentará usarlo para destruirte. –

0

No tiene sentido hacer esto. No agrega ninguna seguridad real.

Todos los encabezados que indican que una solicitud se realiza a través de Ajax (como HTTP_X_REQUESTED_WITH) se pueden falsificar en el lado del cliente.

Si su Ajax está publicando datos confidenciales o permite el acceso a operaciones confidenciales, debe agregar la seguridad adecuada, como un sistema de inicio de sesión.

2

Cualquiera en este hilo que sugiriera mirar los encabezados está mal de una manera u otra. Cualquier cosa en la solicitud (HTTP_REFERER, HTTP_X_REQUESTED_WITH) puede ser falsificada por un atacante que no sea del todo incompetente, incluidos los secretos compartidos [1].

No puede evitar que las personas realicen una solicitud HTTP a su sitio. Lo que quiere hacer es asegurarse de que los usuarios se autentiquen antes de realizar una solicitud a una parte sensible de su sitio, por medio de una cookie de sesión. Si un usuario realiza solicitudes no autenticadas, deténgase allí y bríndeles un HTTP 403.

Su ejemplo hace una solicitud GET, así que supongo que le preocupan los requisitos de recursos de la solicitud [2]. Puede hacer algunas comprobaciones de cordura simples en los encabezados HTTP_REFERER o HTTP_X_REQUESTED_WITH en sus reglas .htaccess para evitar que se generen nuevos procesos para solicitudes obviamente falsas (o robots de búsqueda tontos que no escuchen el archivo robots.txt), pero si el atacante falsifica aquellos, querrá asegurarse de que su proceso de PHP finalice lo más pronto posible para las solicitudes no autenticadas.

[1] Es uno de los problemas fundamentales con las aplicaciones cliente/servidor. He aquí por qué no funciona: supongamos que tiene una forma para que su aplicación cliente se autentique en el servidor, ya sea una contraseña secreta o algún otro método. La información que necesita la aplicación es necesariamente accesible para la aplicación (la contraseña está escondida en alguna parte, o lo que sea). Pero debido a que se ejecuta en la computadora del usuario, eso significa que también tienen acceso a esta información: todo lo que necesitan es mirar el origen, el binario o el tráfico de red entre su aplicación y el servidor, y eventualmente se darán cuenta el mecanismo por el cual su aplicación se autentica y la replica. Quizás incluso lo copien. Tal vez escriban un truco ingenioso para hacer que su aplicación haga el trabajo pesado (siempre puede enviar una entrada falsa del usuario a la aplicación). Pero no importa cómo, tienen toda la información necesaria, y no hay forma de evitar que la tengan, lo que tampoco evitaría que tu aplicación la tenga.

[2] Las solicitudes GET en una aplicación bien diseñada no tienen efectos secundarios, por lo que nadie que las realice podrá realizar cambios en el servidor. Sus solicitudes POST siempre deben estar autenticadas con la sesión más el token CSRF, para permitir que solo los usuarios autenticados los llamen. Si alguien lo ataca, significa que tiene una cuenta contigo y quieres cerrar esa cuenta.

1

Pon el siguiente código en la parte superior de tu archivo php que es llamado por ajax. Ejecutará las solicitudes ajax, pero "morirá" si se llama directamente desde el navegador.

define('AJAX_REQUEST', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'); 
if(!AJAX_REQUEST) {die();} 

Personalmente, elijo no dar salida a nada después de "morir()", como una medida de seguridad adicional. Lo que significa que prefiero mostrar solo una página en blanco al "intruso", en lugar de dar pistas como "si" o "por qué" esta página está protegida.

1

He resuelto este problema preparando una función de comprobación que hacer tres cosas

  1. cheque árbitro $ _SERVER [ 'HTTP_REFERER'];
  2. check http x request $ _SERVER ['HTTP_X_REQUESTED_WITH'];
  3. comprobar el origen a través de un puente de archivo

si los tres pase, que el éxito en ver archivo php llamado por ajax, si uno falla simplemente no lo consigue

Los puntos 1 y 2 ya se explicó, la solución de archivo de puente funciona tan:

puente archivo

immagine el siguiente escenario:

A.php página de llamada a través de ajax b.php y desea impedir el acceso directo a b.php

  • 1) cuando se carga la página A.php genera un código aleatorio complicada
  • 2) el código se copia en un archivo C.txt no accesible directamente desde web (httpd asegurado)
  • 3) al mismo tiempo este código está en claro esculpido en el html prestado de la página A.php (para ejemplo como un atributo del cuerpo, es:

    datos puente = "ehfwiehfe5435ubf37bf3834i"

  • 4) el código esculpido está retrived de JavaScript y se envía a través de AJAX solicitud post para b.php

  • página 5) b.php obtener el código y verificación si existe en el archivo C.txt
  • 6) en caso de coincidencia de código del código esté salido de C.txt y la página b.php es accesible
  • 7) si el código no se envía (en caso de que intente para acceder directamente a la página B ) o no coincide (en caso de que un viejo código atrapado o truco con un código personalizado), B.php page die.

De esta manera se puede acceder a la página B sólo a través de una llamada AJAX generado a partir de la página padre A. La clave para pageB.php se da solamente y nunca de pageA.php

0

He intentado esto

1) en el archivo php principal (desde el que se envía la solicitud ajax) crear sesión con algún valor aleatorio, como $_SESSION['random_value'] = 'code_that_creates_something_random'; Debe estar seguro, esa sesión se crea por encima de $.post.

2) a continuación,

$.post("process_request.php", 
{ 
input_data:$(':input').serializeArray(), 
random_value_to_check:'<?php echo htmlspecialchars($_SESSION['random value'], ENT_QUOTES, "UTF-8"); ?>' 
}, function(result_of_processing) { 
//do something with result (if necessary) 
}); 

3) y en process_request.php

if(isset($_POST['random_value_to_check']) and 
trim($_POST['random_value_to_check']) == trim($_SESSION['random value'])){ 
//do what necessary 
} 

Antes i definida sesión, campo de entrada entonces escondida con valor de sesión, entonces el valor del campo de entrada oculto enviar con el Ajax. Pero luego decidió que el campo de entrada oculto no es necesario, porque puede enviarlo sin él

-2

Probé muchas sugerencias, nadie resolvió el problema. Finalmente, protegí los parámetros del archivo de destino php y era la única manera de limitar el acceso directo al archivo php. ** Al colocar el archivo php y establecer la limitación por.htaccess, se produce un error en la conexión Ajax en la página Html principal.

Cuestiones relacionadas