locked
Prevent uploading .EXE files RRS feed

  • Question

  • User1538291221 posted

    I am using the following code to save any file.

    [HttpPost]
            public JsonResult SalvarInfo()
            {
                try
                {
    
                    var model = JsonConvert.DeserializeObject<ApontamentoViewModel>(Request.Form["model"]);
                    if (!string.IsNullOrWhiteSpace(model.filePath))
                    {
                        //convert to list
                        var listArquivos = model.CaminhoArquivo.Split(';').Distinct().ToList();
    
                        //for each file in the list, move from temporary folder to final folder
                        model.filePath= string.Join(";", listArquivos);
    
    
                        string caminhoRaiz = Server.MapPath(System.Configuration.ConfigurationManager.AppSettings.Get("FinalUploadFolder"));
                        _CaminhoRaizTempUpload = Server.MapPath(System.Configuration.ConfigurationManager.AppSettings.Get("TempUploadFolder"));
    
                        var files = Directory.EnumerateFiles(_CaminhoRaizTempUpload, "*.*", SearchOption.AllDirectories)
                                         .Where(s => listArquivos.Any(arquivo => s.Contains(arquivo)))
                                         .ToList();
    
    
                        files.ForEach(arquivoMover =>
                        {
                            var nomeArquivo = System.IO.Path.GetFileName(arquivoMover);
                            System.IO.File.Move(arquivoMover, System.IO.Path.Combine(caminhoRaiz, nomeArquivo));
    
                        });
    
                    }

    My ideia its to use something like that, to check every file that is on the list, before the user saves.

    Its just a EXAMPLE

    string strExt = //getExtension;
    string strPath = //getPath;
    if (System.IO.File.ReadAllText(strPath).Contains("%PDF-1"))
    {
    Response.Write("<script>alert('Its a Pdf')</script>");
    
    }
    if (System.IO.File.ReadAllText(strPath).Contains("\x4D\x5A") || System.IO.File.ReadAllText(strPath).Contains(".bin�]"))
    {
    Response.Write("<script>alert('Its an Exe')</script>");
    
    }
    
    if (System.IO.File.ReadAllText(strPath).Contains("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1\x00"))
    {
    Response.Write("<script>alert('Its a doc')</script>");
    }


    Tuesday, June 25, 2019 4:24 PM

All replies

  • User753101303 posted

    Hi,

    ReadAllText get the full content as a string (using  a particular encoding) and the pattern you are looking for is at the very beginning of the file, not at any place. So I would use https://docs.microsoft.com/en-us/dotnet/api/system.io.filestream.read?view=netframework-4.8 instead to read just the beginning of the file.

    From a security perspective a "white list" approach is often preferred ie rather than trying to prevent some types you rather check if the file is allowed and anything is forbidden.

    Rather than doing a series of "if" test you could store the extension and the byte sequence in an array and then loop on that.

    Minor and you'll liekly change that but telling the user what you want can be better than why you don't want this file.

    Tuesday, June 25, 2019 4:53 PM
  • User-134105967 posted

    Hi Jason,

    You can make use of FindMimeFromData method from urlmon.dll library. 

    Or you can use the below method if you want to depend on file extension,

    List<string> Whitelist = new List<string>();
    Whitelist.Add("doc");
    Whitelist.Add("pdf";
    Whitelist.Add("txt");
    string fileExtension = Path.GetExtension(fileName).ToLower();
    
    if (string.IsNullOrWhiteSpace(fileExtension) || Whitelist.Any(i => String.Format(CultureInfo.InvariantCulture, "{0}{1}", ".", i) != fileExtension))
    {
        Response.Write("<script>alert('Invalid File')</script>");
    }

    Thursday, June 27, 2019 11:06 AM