2010-09-20 11 views
6

Tengo una aplicación de PHP.PHP: ¿cómo desinfectar los nombres de archivo cargados?

Permito a los usuarios subir archivos a mi aplicación web.

Pregunta: ¿Cuál es la mejor manera de desinfectar los nombres de archivo de los documentos cargados $_FILES["filename"]["tmp_name"] en PHP?

ACTUALIZACIÓN:

¿Puedo tomar un MD5 del nombre del archivo subido y usar eso como el nombre del archivo recién asignado? Si es así, ¿cómo hago eso en PHP?

+0

¿Puedes dar una definición clara de 'sanitize'? Como en MySQL? Una URL? – fredley

+0

Estoy cargando los archivos a mi servidor web. Los archivos pueden ser imágenes, documentos, etc. No quiero colisiones de nombre de archivo.Y no quiero que la gente intente cargar nombres de archivos que podrían no permitirse en mi sistema de archivos. – frooyo

+0

También debe saber qué tipo de archivos les permite cargar. No desea que alguien pueda cargar cosas como archivos html/javascript. – Moses

Respuesta

2

Me limitaré a ejecutar una expresión regular simple que reemplaza cualquier carácter no alfanumérico con un guión bajo (o simplemente eliminar estos caracteres por completo). Asegúrate de conservar la extensión del curso.

Si quiere ir un poco más allá, puede usar la extensión magic mime para asegurarse de que el archivo tenga el mismo formato que la extensión dice que es.

EDIT: Para evitar colisiones de nombre de archivo en un directorio, puede agregar un md5 de usuarios IP + hora actual al nombre del archivo.

+0

¿Qué sucede si cargan 2 documentos al mismo tiempo? – frooyo

+0

Agregue algo de entropía adicional, use un contador para cada archivo que procese: –

+0

Si $ i se incrementa por cada archivo que procesa: '$ filename = $ sanitizedFileName. md5 ($ _ SERVER ["REMOTE_ADDR"]. time(). $ i). $ extension; ' –

-2

Si no está en contra de perder los nombres de archivo reales, lo que suelo hacer es crear un hash del nombre del archivo y configurar el nombre de archivo, si lo que está desarrollando tiene un montón de imágenes cargadas, ayuda a evitar conflictos donde dos nombres de archivo se llaman iguales y se producen sobrescrituras.

hash('md5', $_FILES["filename"]["tmp_name"]); 
+0

¿Quiere decir: ** hash ('md5', $ _FILES [" filename "] [" tmp_name "]) **? – frooyo

+0

Sí, el primer argumento que pasa es el tipo de hash que desea crear y el segundo argumento es la cadena desde la que desea crear el hash. PHP Hash - http://www.php.net/manual/en/function.hash.php – jduren

+0

También sugeriría agregar la práctica de Sam Days así como también se podría agregar la hora actual al nombre del archivo antes del hash, que crearía un incluso más nombre de archivo único. – jduren

3

apuesto a que también se almacena cierta información sobre el archivo de la base de datos. Si esto es correcto, puede usar la clave principal (ID) como nombre de archivo en su servidor y conservar el nombre de archivo original en la base de datos. Esto le da una mayor flexibilidad, porque puede manipular los metadatos sin cambiar el nombre del archivo real.

4

para evitar la colisión de nombre de archivo simplemente comprobar si el nombre de archivo dado o generado no lo hace ya existe:

do { 
    // Generate filename, eg.: 
    $filename = md5(uniqid()) . $fileExtension; 
} while (file_exists($filename)); 

Eso le da el 100% seguro de que el nombre del archivo es único. El uso de md5 (o cualquier otro algoritmo hash) garantiza que el nombre del archivo sea seguro y fácil de manejar.

+2

Esto no tiene sentido. Estás tomando el MD5 de la función uniqid. ¿Por qué? – frooyo

+0

Eso es solo un ejemplo. Puede usar el nombre del archivo original, etc. El punto es que debe verificar en bucle si el nombre del archivo generado ya está en uso. Si es así regenera el nombre del archivo. – Crozin

+3

Tomar md5() de uniqid() no tiene sentido. Tomar md5() del nombre de archivo original (es decir, un valor constante) en un bucle tiene aún menos sentido. :-) – Cucu

0

En lugar de desinfectar los nombres de archivo especificados por el usuario, utilice cualquier otro identificador único para esa foto y almacénelo como el nombre de archivo. Prefiero usar identificaciones de usuario que son numéricas y siempre únicas.

move_uploaded_file($_FILES["tmp_name"],"/home/yourname/".$user_id));

entonces usted puede recuperar la imagen desde cualquier ubicación (por ejemplo, S3 o incluso su propio servidor) por el hecho de saber el ID del usuario. Ni siquiera necesita un atributo en su base de datos para almacenar las URL de la imagen.

0

Ciao, esta función también elimina todos los puntos y luego creo la cadena limpia con la extensión.

function sanitaze_upload_file($data) 
{ 
    $imgName = $data; 
    $indexOFF = strrpos($imgName, '.'); 
    $nameFile = substr($imgName, 0,$indexOFF); 
    $extension = substr($imgName, $indexOFF); 
    $clean  = preg_replace("([^\w\s\d\-_~,;\[\]\(\)])", "", 
    $nameFile); 
    $NAMEFILE = str_replace(' ', '', $clean).$extension; 
    return $NAMEFILE; 
} 
Cuestiones relacionadas