Subir archivos a WordPress: cómo evitar que un upload se convierta en una puerta de entrada

Un formulario que permite subir imágenes, documentos o archivos de usuarios puede parecer una función sencilla. En realidad, es una de las partes que más cuidado necesita en una aplicación web.
El problema no es únicamente que alguien suba un archivo con una extensión extraña. También puede intentar falsificar el tipo declarado, aprovechar un nombre especialmente preparado, llenar el disco, abusar de un procesador de imágenes o conseguir que el servidor interprete como código algo que debía ser un documento.
Todo archivo que sube un usuario debe considerarse hostil hasta que la aplicación demuestre qué es, dónde se puede guardar y cómo se podrá servir.
El nombre y la extensión no demuestran qué contiene un archivo
Un archivo llamado foto.jpg puede no ser una imagen. La extensión forma parte del nombre que controla el usuario y el encabezado Content-Type enviado por el navegador también se puede falsificar.
Por eso no basta con comprobar que el nombre termina en .jpg, .png o .pdf. La aplicación debería utilizar una lista blanca de tipos permitidos y comprobar el contenido real con las herramientas apropiadas para cada formato. OWASP recomienda no confiar en el Content-Type y advierte de que la firma del archivo tampoco debe utilizarse como única comprobación. OWASP: File Upload Cheat Sheet
En WordPress, esto debe revisarse tanto en los formularios públicos como en los plugins que añaden campos de subida al área privada. Un plugin puede aplicar sus propias reglas y no comportarse igual que la biblioteca multimedia nativa.
Renombra el archivo antes de guardarlo
No conviene escribir en disco utilizando directamente el nombre recibido del navegador. El nombre puede incluir caracteres problemáticos, rutas, secuencias inesperadas o información que facilite sobrescribir otro archivo.
La aplicación debería generar un nombre propio, preferiblemente aleatorio, y conservar el nombre original únicamente como dato descriptivo si hace falta mostrarlo al usuario. También conviene limitar la longitud y los caracteres aceptados.
Esto no sustituye a la validación del contenido. Un archivo malicioso con un nombre aleatorio sigue siendo malicioso. El renombrado evita algunos problemas de escritura y reduce la capacidad del atacante para controlar la ruta o predecir nombres.
No guardes todo dentro del webroot sin una razón
La carpeta de subidas suele estar pensada para que los archivos puedan servirse desde una URL pública. Esa comodidad también significa que cualquier archivo almacenado allí puede quedar accesible si se conoce o se adivina su dirección.
Cuando los archivos contienen información privada, la opción más segura suele ser almacenarlos fuera del webroot o detrás de un endpoint que compruebe permisos antes de entregarlos. Un documento subido por un usuario no debería hacerse público por accidente solo porque WordPress utilice una ruta accesible desde el navegador.
Bloquea la ejecución de PHP en uploads
Una carpeta de uploads debería servir archivos permitidos, no ejecutar scripts enviados por usuarios. Si el servidor interpreta un archivo PHP guardado allí, una subida insegura puede convertirse en una vía de ejecución de código.
En Nginx, WordPress documenta una regla para denegar el acceso a archivos .php dentro de uploads o files. En Apache, la configuración equivalente depende del módulo y de las reglas activas, por lo que no conviene copiar una solución sin comprobar cómo está montado el servidor. WordPress: configuración de Nginx
Esta protección no arregla un formulario que acepta archivos peligrosos, pero limita el impacto de un fallo de validación. Es una capa de contención: si una aplicación permite que algo llegue a la carpeta, el servidor todavía debería impedir que se ejecute como código.
Después de aplicar una regla, prueba las subidas legítimas. Una configuración demasiado amplia puede romper imágenes, documentos, miniaturas o integraciones que utilizan rutas de uploads.
Limita tamaño, cantidad y frecuencia
Un archivo que no contiene código puede seguir siendo una herramienta de abuso. Un atacante puede subir archivos enormes, repetir la operación cientos de veces o provocar que un procesador consuma demasiada CPU y memoria.
Define límites coherentes para cada formulario:
- Tamaño máximo por archivo.
- Número máximo de archivos por operación.
- Espacio total disponible por usuario.
- Tipos y extensiones permitidos.
- Número de intentos en un intervalo.
Estos límites deben existir en la aplicación y también en el servidor.
Reprocesar imágenes ayuda, pero no es una garantía
Las imágenes pueden contener metadatos, estructuras inesperadas o cargas dirigidas a la biblioteca que las procesa. Una práctica útil consiste en decodificar y volver a codificar la imagen en un formato permitido, eliminando metadatos que no sean necesarios.
Pero reprocesar no convierte automáticamente una subida en segura. La librería debe estar actualizada, configurada con límites de recursos y aislada cuando el riesgo lo justifique. OWASP advierte de que reescribir una imagen no garantiza eliminar todo el contenido malicioso y de que el propio procesador debe tratarse como código que recibe datos no confiables. OWASP: validación del contenido de archivos
No aceptes archivos comprimidos o documentos complejos sin una razón clara. Cada formato adicional aumenta el número de parsers, librerías y casos que hay que mantener.
Revisa quién puede subir archivos
No todos los formularios necesitan estar abiertos a visitantes anónimos. Si la función está destinada a clientes, editores o usuarios registrados, exige autenticación y aplica permisos concretos.
Comprueba también qué ocurre cuando un usuario pierde su cuenta, cambia de rol o intenta acceder a un archivo subido por otra persona. La autorización no debe limitarse al momento de la subida: también debe comprobarse al descargar, modificar o borrar el archivo.
En WordPress, un plugin que permite subir archivos puede ampliar mucho la superficie de ataque de la instalación. Mantén actualizado el core y revisa los plugins que gestionan uploads. Las actualizaciones y la revisión periódica forman parte del mantenimiento y seguridad de WordPress.
Checklist antes de dar por seguro un formulario
Antes de dejar activo un formulario de subida, comprueba:
- Se utiliza una lista blanca de formatos realmente necesarios.
- No se confía únicamente en la extensión o en
Content-Type. - El archivo se renombra en el servidor.
- El tamaño y la cantidad están limitados.
- Los archivos privados no quedan expuestos mediante una URL directa.
uploadsno permite ejecutar PHP.- Las imágenes se procesan con una librería actualizada y límites de recursos.
- Se exige autenticación cuando la función lo permite.
- Se registran los errores y los intentos rechazados.
- Existe una copia recuperable antes de cambiar reglas del servidor.
Si aparecen archivos PHP en uploads, subidas que no corresponden a ninguna función legítima, usuarios desconocidos o cambios que reaparecen, no borres todo a ciegas. Conserva las evidencias y solicita una auditoría de seguridad WordPress o una revisión especializada de desinfección web.
Un upload seguro no depende de una única comprobación. Necesita validación del contenido, nombres controlados, límites, permisos, almacenamiento adecuado y un servidor que no ejecute lo que solo debería entregar como archivo.
Fuentes
¿Crees que han comprometido tu web?
Antes de borrar archivos o restaurar una copia, conserva las evidencias y revisa qué ha ocurrido.
Analizar mi web

