2010-08-05 11 views
6

Estoy usando UNLINK con PHP y AJAX. Sé que de esta manera es muy peligroso, porque todos pueden eliminar cualquier archivo. Pero necesito usar AJAX porque no puedo volver a cargar la página cuando borro los archivos.¿Cómo evitar los riesgos de seguridad de UNLINK en PHP?

Entonces, ¿cómo debo hacer para permitir que se elimine el archivo solo para el usuario que lo posee?

por favor hágamelo saber otras cosas también si usted piensa que estoy haciendo aquí algo mal o algo más de lo que tiene en mente y cree que será útil:)

Mi código PHP:


<?php 

    $photo_id  = $_GET['photo_id']; 
    $thumbnail_id = $_GET['thumbnail_id'];  

    function deletePhotos($id){ 
     return unlink($id); 
    } 

    if(isset($photo_id)){ 
     deletePhotos($photo_id); 
    } 
    if(isset($thumbnail_id)){ 
     deletePhotos($thumbnail_id); 
    } 


?> 

Mi código AJAX:


function deletePhoto(photo, thumbnail){ 

     var photos = encodeURIComponent(photo); 
     var thumbnails = encodeURIComponent(thumbnail); 

     if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari 
      xmlhttp=new XMLHttpRequest(); 
     } else {// code for IE6, IE5 
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
     } 

     xmlhttp.onreadystatechange=function() { 
      if (xmlhttp.readyState==4 && xmlhttp.status==200) { 
       document.getElementById("media").innerHTML=xmlhttp.responseText; 
      } 
     } 
     xmlhttp.open("GET", "http://192.168.2.104/images/users/delete_photo.php?photo_id="+photos+"&thumbnail_id="+thumbnails, true); 
     xmlhttp.send(); 
    } 
+0

AJAX tiene nada que ver con seguridad Desde el punto de vista del servidor, la llamada AJAX no es diferente de una normal. Su problema no está en AJAX sino en falta de autorización. Cuanto antes lo comprenda, más pronto resolverá su problema. –

+0

Hola @Col. Shrapnel, no creo que tengas toda la razón, porque sin 'AJAX' no necesito hacer un archivo al que cualquiera pueda acceder y pueda eliminar cualquier cosa con una solicitud GET. De lo contrario, sé que el problema aquí es con la autorización, es por eso que hice esta pregunta 'Entonces, ¿cómo debo hacer para permitir que se elimine el archivo solo para el usuario que lo posee?' – Adam

+0

¿cómo se puede dejar que el usuario elimine un archivo sin tal ¿un guión? –

Respuesta

7

Necesita autenticar al usuario de alguna manera.

Su usuario debe estar autenticado con un nombre de usuario y una contraseña.

La sesión de PHP se puede utilizar para recordar, y debe usar una tabla de base de datos o un archivo de texto en el servidor para almacenar la información de propiedad del archivo.

Luego, antes de desvincular todo, su lógica debe asegurarse de que el usuario actualmente "autenticado" sea el propietario del archivo.

+0

Si quiere decir iniciar sesión, entonces el usuario ha iniciado sesión. Si no le permito a los usuarios acceder al archivo que no está conectado, eso es un poco mejor, pero los usuarios que están conectados están aún puede eliminar los archivos de los demás. – Adam

+0

es por eso que necesita almacenar la propiedad del archivo en otra tabla, y antes de desvincular todo, asegúrese de que el usuario "autenticado" es el propietario del archivo. –

+0

la única respuesta sensata aquí. @CIRK escucha ese comentario anterior. esa es la única solución. Estás yendo totalmente mal. AJAX no es tu problema –

2

Limite la desvinculación al directorio con las fotos. Es decir, no permita .. en la ruta, o verifique la ruta completa después de hacer realpath(). De lo contrario, el usuario puede solicitar delete_photo.php?photo_id=../../../../etc/passwd y romper el sistema.

+0

Si codifican '..' en un juego de caracteres diferente, podría pasar. He leído sobre esto en el pasado. –

+0

@Wadih sí, pero ese fue un error (creo que en Apache) que se solucionó desde entonces. –

+1

Si php se ejecuta como root, creo que tienes problemas mayores en tus manos. – rook

1

En su PHP:

  • Asegúrese de $ _GET [ 'photo_id'] y $ _GET [ 'thumbnail_id'] no contienen "../"
  • También asegúrese de poner un prefijo BasePath a la ID.

De lo contrario, los usuarios pueden eliminar cualquier archivo.

En cuanto a la propiedad, debe almacenar la información a la que pertenece el archivo en algún lado del servidor (por ejemplo, un MySql-DB). Luego debe consultar esta ubicación antes de eliminar el archivo.

-1

Una sugerencia diferente: no almacene archivos en el disco, sino guárdelos en una base de datos. Esto mantiene una distinción muy clara entre su sitio + scripts y "datos de usuario".

(Alguien me dijo una vez que los archivos eran archivos, y las bases de datos eran para datos, y que son diferentes, pero como yo veo, los archivos contienen datos de todos modos. Mysql tiene un tipo LONGBLOB perfecto para poner cualquier cosa, y puedes almacenar metadatos, como tipo de archivo y nombre de archivo, en campos separados en la misma fila de datos, lo que mantiene las cosas limpias y simples)

+0

En el caso de las imágenes, no creo que sea una buena idea almacenarlas en la base de datos (por razones de rendimiento). Porque al mostrarlos, necesitas un script PHP para leer desde la base de datos. Como las imágenes son solicitudes HTTP separadas, esto dará lugar a múltiples conexiones a la base de datos, que deben establecerse. – JochenJung

+0

+1 esta es una buena idea. – rook

+0

Fyi, Microsoft SharePoint 3.0 hace eso (almacena archivos en la base de datos). No necesariamente estoy de acuerdo con esta decisión, ya que soy partidario de que el "sistema de archivos" se use para almacenar "archivos" y "bases de datos" para datos tabulares. Pero este patrón de diseño tendría sentido en algunos escenarios. –

0

As Wadih M. ha dicho. Necesita autenticar a su usuario.Entonces puede usar eso para comparar el "Dueño de la Imagen" con el "Usuario actualmente ingrese". Esto le dará toda la seguridad que pueda desear.

Como dije antes, nombre los varaibles para que suenen bien. Cuando veo "id" en un varaiable. Asumo automáticamente como programador que es una var numérica.

+0

La ID no es un número: D es el 'nombre_archivo' con algunas cosas únicas antes que ellos, algo así como' efb03_orange.png'. El problema es que en esta sección no he enviado nada aún a la base de datos. Así que no sé cómo verificar si el usuario que inició sesión es el usuario propietario del archivo. – Adam

+0

Creo que ese tipo de convención de nomenclatura de ruptura para la var. Debería ser como $ imagePlaceholder. Voy a hacer más actualizaciones en respuesta a su comentario. – Anraiki

+0

Me acabo de dar cuenta de que ... hacer que la persona salte más aro puede no ser necesaria una vez que se realiza la "verificación" del propietario del archivo. – Anraiki

2

puede simplificar su tarea mediante el uso de una sustitución de base de datos muy simple: una estructura de directorios. mantener los archivos del usuario en el directorio del usuario. por lo tanto, siempre puede verificar si un usuario en particular tiene derechos para eliminar. Nombrar un directorio después del nombre del usuario, o - mucho mejor - numérico identificador de usuario

simplemente algo así como

$photo_id = basename($_GET['photo_id'];) 
$filename = $filebase.$_SESSION['user_id']."/".$photo_id; 
if (file_exists($filename) unlink ($filename); 
0

han tenido el mismo problema, pero he alrededor de ella utilizando la función de PHP ftp_delete

Cuestiones relacionadas