Advertencia: El ningún caso me hago responsable del mal uso que se le pueda dar a la información que a continuación voy a presentar. Se presenta “tal cual” con el objetivo de que los usuarios de la conocida plataforma de publicación que a continuación se menciona tomen medidas preventivas urgentes para evitar que sus blogs sean perjudicados.
Si hace unos meses fue BlogEngine.net 1.1 ahora es el turno para su nueva release: BlogEngine.net 1.2. En esta ocasión voy a describiros el procedimiento a seguir para subir cualquier archivo a un servidor dónde estén usando BlogEngine 1.2.
El proceso es fácil, pero uno podría perderse también con facilidad. Para llevar a cabo esta receta, necesitaremos al menos alguna versión Express de Visual Studio 2005 y un espacio dónde subir un fichero y se pueda acceder a él a través de una URL. Pues bien, buscamos la instancia de BlogEngine.net 1.2 a la cual queremos acceder y comprobamos que, en efecto, tienen el servicio web para importar blogs (http://www.ejemplo.com/api/BlogImport.asmx).
Al abrir la url del sitio que queremos comprobar, encontraremos algo del estilo de:
BlogImporter
The following operations are supported. For a formal definition, please review the Service Description.
* AddComment
* AddPost
* BlogFileHandler
* BlogImageHandler
* BlogType
* BlogVersion
* GetFile
Los iniciados en .NET WebServices reconocerán al instante este tipo de página. Así, si añadimos una referencia web a un proyecto podremos hacer uso de este WebService “previa autenticación”.
Comprobado tal cosa y que la versión ejecutándose en la 1.2.0.0, abrimos una instancia de Visual Studio (o bien cualquier cosa que os permita interactuar con servicios web SOAP, pero la costumbre es la costumbre).
De todas las funciones de este WebService, por alguna razón, GetFile no valida que el usuario esté autentificado (requerir una cabecera SOAP llamada AuthenticationHeader no autentica a nadie).
El método GetFile tiene dos parámetros: source y destination. En source especificaremos la URI completa del recurso a descargar. Por ejemplo, podríamos tener un archivo *.png en este blog y subirlo. En destination, escribimos el nombre y la ruta que queremos darle al archivo. Por defecto, se almacenará en App_Data/Files pero haciendo uso de la canonicalización podremos ponerlo en cualquiera de los directorios del sitio web o incluso la máquina.
Así, por ejemplo, con una llamada de este tipo:
GetFile("http://rafavargas.files.wordpress.com/2007/09/banner-verde.thumbnail.png", "..\..\pics\Imagen.png") subiriamos esta imagen y sería accesible desde http://www.ejemplo.com/pics/Imagen.png.
También podríamos crear un Handler, guardarlo como *.txt en cualquier servidor, subirlo al servidor ejemplo.com con el nombre cambiado a *.ashx y conseguir ejecutar lo que quisieramos en el servidor. Las ideas os la dejo a la imaginación. (Pista: las contraseñas se guardan sin encriptar).
Pregunta: ¿cómo fortifico mi BlogEngine.net 1.2.0.0? Me gusta mucho y no quiero migrar a otro sistema de publicación.
Respuesta: elimina la carpeta “~/setup” y el servicio web (si no vas a importar ningún blog) o bien corrije las siguientes lineas en el servicio:
///
/// Downloads specified file to specified location
///
/// source file path
/// relative destination path
///
[SoapHeader("AuthenticationHeader")]
[WebMethod]
public bool GetFile(string source, string destination)
{
bool response;
//Anyade las siguientes dos lineas:
if (!IsAuthenticated())
throw new InvalidOperationException("Wrong credentials");
try
{
string rootPath = BlogSettings.Instance.StorageLocation + "files/";
string serverPath = Server.MapPath(rootPath);
string saveFolder = serverPath;
string fileName = destination;
// Check/Create Folders & Fix fileName
if (fileName.LastIndexOf('/') > -1)
{
saveFolder += fileName.Substring(0, fileName.LastIndexOf('/'));
saveFolder = saveFolder.Replace('/', '\\');
fileName = fileName.Substring(fileName.LastIndexOf('/') + 1);
}
else
{
if (saveFolder.EndsWith("\\"))
saveFolder = saveFolder.Substring(0, saveFolder.Length - 1);
}
if (!Directory.Exists(saveFolder))
Directory.CreateDirectory(saveFolder);
saveFolder += "\\";
using (WebClient client = new WebClient())
{
client.DownloadFile(source, saveFolder + fileName);
}
response = true;
}
catch (Exception)
{
// The file probably didn't exist. No action needed.
response = false;
}
return response;
}
Ahora ya conoceis los riesgos de instalar BlogEngine. Nunca pongais en producción (y menos de manera web) algo que no auditeis.

Buen trabajo, no se si has avisado ya pero si no ponle un correito a Mads Kristensen.
Y sobre la cabecera SOAP, si no tienes SSL ( como le ocurre al 99% de los blogs ) pues que otra alternativa más segura puede haber ?
Yo utilizo OpenID pero las librerías requieren Full Trust… casi peor el remedio que la enfermedad
La última vez que le envié un correito pasó bastante del tema… de hecho, en BlogEngine 1.2 se siguen manteniendo ciertas malas costumbres (no hashear las contraseñas, permitir a la gente con acceso leer la configuración de SMTP, etc…).
Bueno, pues si pasó del tema entonces retiro lo dicho. Pero es muy llamativo, parece que se preocupan más de añadir nuevas funcionalidades que estabilizar el producto.
Y no les va nada mal…
Felicidades por informar en cualquier caso, ojalá se le de la importancia que merece
La gente de BlogEngine.net piensa al microsoft-way-to-do-things y en cada nueva versión añaden más y más funcionalidades hasta que lleguen al punto dónde la aplicación web se vuelva pesada e insostenible.