Subida de ficheros segura en PHP: lo que reviso siempre

Sergio
12 de Agosto del 2026

Con varios hilos por aquí de subida de ficheros en PHP, van los puntos que reviso siempre en un formulario de subida, porque los fallos de seguridad más comunes vienen todos de saltarse alguno de estos:

1. Nunca confiar en la extensión del nombre de fichero. Un atacante puede subir shell.php renombrado a foto.jpg con contenido PHP real dentro. Comprobar el tipo real de contenido con finfo_file(), no con pathinfo($nombre, PATHINFO_EXTENSION):

$finfo = finfo_open(FILEINFO_MIME_TYPE);
$tipo_real = finfo_file($finfo, $_FILES['archivo']['tmp_name']);
finfo_close($finfo);

$permitidos = ['image/jpeg', 'image/png', 'image/webp'];
if (!in_array($tipo_real, $permitidos, true)) {
    throw new Exception('Tipo de fichero no permitido');
}

2. Nunca guardar el fichero con el nombre que envía el usuario. Genera un nombre nuevo (por ejemplo con bin2hex(random_bytes(16))) y guarda el nombre original solo como metadato en base de datos si lo necesitas mostrar después. Evita tanto ataques de path traversal (../../etc/passwd) como colisiones de nombres.

3. El directorio de subida no debe ser ejecutable. Si usas Apache o Nginx, configura ese directorio para que sirva ficheros estáticos pero nunca ejecute PHP, ni aunque alguien consiga colar un .php disfrazado. Es la última línea de defensa cuando fallan las dos anteriores.

4. Limitar el tamaño, tanto en PHP (upload_max_filesize/post_max_size en php.ini) como comprobando $_FILES['archivo']['size'] en tu código, porque un usuario malicioso puede saltarse cualquier límite puesto solo en el HTML del formulario (el atributo max de un input, por ejemplo, no protege nada por sí solo).

¿Algún otro punto que añadiríais a la lista?

Sergio