¿Cómo evitar los riesgos de seguridad desenlazar en PHP?
-
26-09-2019 - |
Pregunta
Estoy usando UNLINK con PHP
y AJAX
. Sé que de esta manera es muy peligroso, porque todo el mundo puede eliminar cualquier archivo. Pero necesito utilizar AJAX
porque no puedo recargar la página cuando se borra los archivos.
¿Cómo debo hacer para permitir borrar el archivo sólo para el usuario que es el propietario?
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();
}
Solución
Es necesario para autenticar al usuario de alguna manera.
Sus necesidades de los usuarios a autenticarse con un nombre de usuario y una contraseña.
sesión de PHP puede ser usado para recordar, y se debe utilizar una tabla de base de datos o un archivo de texto en el servidor para almacenar información de archivo de la propiedad.
A continuación, antes que cualquier desvinculación, la lógica debe asegurarse de que el usuario actualmente "autenticado" es el propietario del archivo.
Otros consejos
Puede simplificar su tarea mediante una simple sustitución de base de datos - una estructura de directorios. mantener los archivos de usuario en el directorio del usuario. Por lo tanto, siempre se puede comprobar si el usuario 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);
Limitar la desvinculación al directorio con las fotos. Es decir, no permiten ..
en el camino, o comprobar la ruta completa después de hacer la ruta real (). De lo contrario, el usuario puede solicitar delete_photo.php?photo_id=../../../../etc/passwd
y romper el sistema.
En su PHP:
- Asegúrese de $ _GET [ 'photo_id'] y $ _GET [ 'thumbnail_id'] no contienen" ../"
- También asegúrese de que preceder una ruta base a la ID.
De lo contrario los usuarios pueden eliminar cualquier archivo.
En cuanto a la propiedad, usted tiene que almacenar la información que posee, que en algún archivo en el lado del servidor (por ejemplo, un MySQL-DB). A continuación, usted debe consultar a este lugar antes de borrar el archivo.
Como Wadih M. ha dicho. Es necesario para autenticar su usuario. A continuación, puede utilizar eso para comparar el "dueño de la imagen" para el "Usuario actualmente conectarse". Esto le dará toda la seguridad es posible que desee.
Como he dicho antes, el nombre de la varaibles para que suenen bien. Cuando veo "id" en un varaiable. Asumo automáticamente como un programador que es una var numérico.
han tenido el mismo problema y conseguir alrededor de él usando la función PHP ftp_delete
Una sugerencia diferente: no almacenar archivos en el disco, pero los puso en una base de datos. Esto mantiene una distinción muy clara entre las secuencias de comandos del sitio + y "datos de usuario".
(alguien me dijo una vez que los archivos eran archivos y bases de datos eran para los datos, y los que son diferentes, pero como yo lo veo, archivos contienen datos de todos modos. MySQL tiene un tipo LONGBLOB perfecto para poner cualquier cosa en, y se puede almacenar los meta-datos, tales como tipo de archivo y nombre de archivo, en campos separados en la misma fila de datos, lo que mantiene las cosas limpias y sencillas)