Incorrect mime for XLS files

2

I'm doing a migration of a certain system written in ASP.NET (site) and in a certain part of that system there is a place where a XLS file is uploaded.

There is a check against the mime type of the file to see if it is actually an XLS file.

This worked fine on the old server, but after migration, both on my machine (Windows 7 Ultimate SP1) and on the production server (Windows 2016 Datacenter) the XLS file mimes are recognized as "application / octet-stream ".

Just to note: I do not have Microsoft Office installed on my machine or on the server (and I think it would be a long delay to depend on it just to have the right mimes). And I also find it improbable that I should change the code to check the extension, as this does not bring any kind of benefit to the security of the application.

Is there any way to make this mime really recognizable?

The code snippet is as follows:

string Type = UP_Dados.PostedFile.ContentType;

string[] AllowedTypes = {
    "application/vnd.ms-excel", "application/ms-excel", "application/x-msexcel"
};

if (! System.Linq.Enumerable.Contains(AllowedTypes, Type))
{
    Page.RegisterStartupScript(",", "<script>alert('O arquivo deve ser um XLS')</script>");

    return;
}
    
asked by anonymous 14.07.2017 / 13:43

1 answer

0

The HttpPostedFile.ContentType does not get the mime-type of the file during execution, it takes the content-type that browser payload during the request, that is, you determined this content-type that you see was the browser, ie the content detection occurs before uploading and occurs on the user.

I'm just saying that it's not such a reliable way, since any HTTP request can be manipulated.

For example in a request to upload a valid file I made, called 2.xls , resulted in this:

POST /upload HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
Content-Length: 27329
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryjUAtIb3hLXspUBmo
Host: localhost
Origin: http://localhost
Referer: http://localhost/form
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36 OPR/49.0.2725.47

------WebKitFormBoundaryjUAtIb3hLXspUBmo
Content-Disposition: form-data; name="file"; filename="2.xls"
Content-Type: application/vnd.ms-excel


------WebKitFormBoundaryjUAtIb3hLXspUBmo--

Now this was the result of an invalid xls file, called 3.xls, which is actually just a text file containing just this foo bar  the result was (I summarized the result to show only the relevant part):

------WebKitFormBoundarySMenF7hr3QNf4T6l
Content-Disposition: form-data; name="file"; filename="3.xls"
Content-Type: application/vnd.ms-excel


------WebKitFormBoundarySMenF7hr3QNf4T6l--

See, he has accused it of being application/vnd.ms-excel , that is not what is expected.

File upload doc, docx, xls, xlsx, ppt, pptx appear as "application / octet-stream"?

I know that in my example application/vnd.ms-excel appeared, but this is the point I want to get, I'm not sure of the conditions that the upload was made, but one thing I can tell you, if you're using an older browser, I have Note that most modern browsers, even IE11, try to do a good job of detecting and passing on the most correct mime-type for a specific file type, but really can not guarantee.

I even looked for some package via NuGet: link , but I only found the ones that guess by extension of the file, ie it would not be a mime-type detection but a map, which would not be very interesting, as it would install something else for something that you could simply validate using something like:

using System.IO;

...

string Nome = UP_Dados.PostedFile.FileName;

if (Path.GetExtension(Nome).ToLower() == ".xls") {
      //Validou
} else {
      //Não validou
}

The most I found of something that could supposedly work for this is the FindMimeFromData ", which is not native to C # , it is part of urlmon.dll , what I found of usage attempts were:

However when I test 3 files, the 1.xlsx , 2.xls and 3.xls (false file), I get this result:

  

ItisimportanttonotethaturlmonisapartofInternetExplorerthatisinstalledonyourserver,myIEisthemostupdatedandeventhenthese3documentswerenotrecognized,sothesolutionisnotasfunctionalasexpected(Itriedthetwoanswerslinkedabove)

Howtosolveformime-type?

Youcannotdothisforawhile,atleastIdidnotfindanysolutionthatusesforexampleacopyofthefileMAGIC( link ), so for now the closest solution would be to check ContenType (even if it is something that can be manipulated) and if application/octet-stream appears then it would use a fallback to check the extension, something like this:

using System;
using System.IO;
using System.Linq;

...

string ContentType = UP_Dados.PostedFile.ContentType;
string FileName = UP_Dados.PostedFile.FileName;
bool validate = false;

string[] AllowedTypes = {
    "application/excel",
    "application/x-excel",
    "application/ms-excel",
    "application/x-msexcel",
    "application/vnd.ms-excel",
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
};

//Para o fallback, acaso o navegador enviar a extensão octet-stream ou zip
string[] FallckExtensions = { ".xls", ".xlsx" };
string[] FallbackMimes = {
    "application/zip",
    "application/octet-stream",
    "application/x-zip-compressed"
};

//Se ContentType for um dos FallbackMimes, então checa a extensão
if (FallbackMimes.Contains(ContentType)) {
    string extension = Path.GetExtension(FileName).ToLower();
    validate = FallckExtensions.Contains(extension);
} else {
    //Se o ContentType enviado pelo navegador não for octet-stream ou zip testa o AllowedTypes
    validate = AllowedTypes.Contains(ContentType);
}

Example on ideone

  

If it is not working with XLSX then remove it from the script:

  • % with% of% with%
  • % with% of% with%
  • ".xlsx" and AllowedExtensions "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
  

Note: If you find a better solution I will review the answer.

    
13.12.2017 / 04:02