As Steffen Ullrich said, it's not sufficient to consider a single application alone, but I'll write my answer assuming the user/application receiving the file trusts these uploads (which is bad if the file comes directly from an untrusted user).
On Windows, (I don't use Windows right now) the identification of file type, and thus what program(s) to read/run it with, is mostly done with file extensions. This means a .pdf
will be opened by a PDF reader by default, and should fail if the file is actually a .exe
file with a .pdf
extension. However, since the user, assuming they're not very computer-literate, may change some things to get it to work, such as renaming the file or changing what program to run the file with, all without understanding what problems that would cause. Additionally, there's the option to hide file extensions on Windows, meaning a file not_a_virus.pdf.exe
would be seen by the user as not_a_virus.pdf
while have a .exe
extension. Some programs may also check the file's MIME type like a Linux system would, which I'll discuss next.
On Linux systems (a lot of web servers are Linux), the file type is determined not (mainly) by file extensions, but by MIME types, using magic bytes. Binary files should have some magic bytes at the beginning of the file to identify the MIME type, as listed on Wikipedia. If a file has the bytes 47 49 46 38 37 61
at the beginning, running file my_file
should return my_file: GIF image data, version 87a,
, since those are the magic bytes of GIF files. Also, if a script (text) file has the line #!/bin/bash
on the first line, it will be identified as a "bash script", and running ./my_script
will use the bash
binary to read/run the file.
As per best practice, you should validate both the file extensions & the file contents. Some programs use only the file extensions, some use only the contents (magic bytes), and some use both to identify the file type. You should simply assume the worst and not trust user inputs.