Hace tiempo que me ronda este post en la cabeza y nunca me he decidido a escribirlo. Hoy he sacado un poco de tiempo y he montado un ejemplo sobre lo peligroso que puede ser el no tratar con mucho cuidado la subida de archivos al servidor desde una aplicación web, en este caso ASP.NET WebForms, pero esto aplica también a MVC.
Código fuente:
https://github.com/lurumad/upload-files-vulnerability
La aplicación que he montado es supersencilla. Un página Default.aspx con un formulario que sube un archivo a un directorio que se llama Public. Imaginad que esta página es la página del perfil de usuario, donde cada usuario puede seleccionar su foto. Lo correcto sería restringir la extensión de los archivos a subir de tipo imagen (jpeg, jpg, png…), pero imaginad que el programador ha pasado por alto esta tarea no pensando lo que puede ocurrir porque no conoce que lo que está en el root del sitio web se ejecuta :p.
Ahora, un usuario un poco espabilado, le da por copiar la url de la foto de su pefil y se da cuenta que estamos subiendo dicha foto a una carpeta pública que se llama también Public, entonces dicho usuario se decide a probar si en dicho formulario de subida se está controlando el tipo de archivo que se sube. Se crea una página llamada HackPage.aspx junto con su archivo de Code Behind HackPage.aspx.cs y lo sube al servidor (Estos archivos los tenéis en el proyecto para que hagáis pruebas):

HackPage.aspx.cs lee el contenido del fichero Web.Config y lo muestra como fichero xml.
public partial class HackPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var serverPath = Server.MapPath("/");
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.Buffer = true;
Response.ContentType = "text/xml";
Response.BinaryWrite(File.ReadAllBytes(Path.Combine(serverPath, "Web.Config")));
Response.End();
}
}
Teclea la url:
http://localhost:56023/public/hackpage
y… ¿Que creéis que ocurrirá?

Ojo! Esto es una prueba en local, pero estoy seguro que haciendo una búsqueda por Google no tardaría mucho en encontrar webs con este fallo de seguridad y por supuesto, esto no es una vulnerabilidad de ASP.NET, Tú has introducido una vulnerabilidad en tu aplicación web por no validar la subida de archivos a tu servidor.
Recomendaciones
- Restringir el tipo de archivos que el usuario puede subir en nuestra aplicación.
- Mover la carpeta de subida de ficheros fuera del root de la aplicación web. Siempre pudes usar un storage alternativo como SkyDrive, Dropbox, Azure Storage, Amazon S3…
Un saludo y Happy Coding!