1

I'm trying to prevent uploading directly executable file types. Is there a reliable way to check if a file is an executable program or just a passive data file?

For example:

example.exe // Directly runable, consider dangerous
example.txt // Not Directly runable, consider "safe"
example.bat // Directly runable?, consider dangerous
example.doc // Not Directly runable, consider "safe"
Slava
  • 2,887
  • 3
  • 30
  • 39
  • 2
    if you're working on windows only, then there's merely a few bajillion file extensions that are "executable" - e.g. did you know screensaver .scr are really executables? you'd have to parse the file headers and look for magic numbers, e.g. look for "MZ", which is the standard first couple chars for windows/dos executables. – Marc B Feb 04 '16 at 14:22
  • Yes I'm aware of .scr and that there is a huge amount of file extensions out there. I just don't know what makes a file executable. Is it something within a file? Is there a list of executable extensions stored somewhere in the OS? Is it both? Is it reliably readable? Is such a check already implemented by somebody? – Slava Feb 04 '16 at 14:29
  • 1
    like I said, most .exe-type files (including .scr) start with `MZ` as the first couple chars. and even then, that doesn't cover everything. e.g. a word file with macros in it. technically that's "executable" as well, without ever looking like a .exe – Marc B Feb 04 '16 at 14:31
  • @Marc Let's ignore files like Word documents as a word document by itself can't do anything. It needs at least MS Word to do the damage. Is reading `MZ` chars reliable? Can one create .exe file without `MZ` and still execute it? – Slava Feb 04 '16 at 15:47
  • sure, there's old-school .com executables, "core memory". they were basically a dump of an up-to 64k memory block, and .com files were loaded by msdos into ram and then perform an unconditional `jmp` to the start of the block - you could name ANY file foo.com and crash the pc by trying to run it. they could start with anything, since it was a raw memory dump of machine code. – Marc B Feb 04 '16 at 15:49
  • 1
    maybe interesting? [Block upload of executable images (PHP)](http://stackoverflow.com/questions/2851976/block-upload-of-executable-images-php). Also: [Security threats with uploads](http://stackoverflow.com/questions/11061355/security-threats-with-uploads) – Ryan Vincent Feb 04 '16 at 16:06
  • What about any file containing any scripting language? It's just text... unless interpreted by the right program... which may or may not automatically spring into action when you try to "execute" the file... (shebang lines, web server context, who-knows-what...) – deceze Feb 04 '16 at 16:55

1 Answers1

1

Well, there is is_executable().

Justin McAleer
  • 236
  • 1
  • 9
  • 1
    That just uses `stat()` to see if the file's got the executable bit set. that doesn't tell you anything about what's actually in the file. ANY file can be set to be executable, but not all of them will actually be executable. – Marc B Feb 04 '16 at 14:30
  • @MarcB just curious, how do you come to know that is_executable uses `stat()`? – shyammakwana.me Aug 06 '16 at 18:35
  • where else is the metadata from a file going to come from? it'd be highly inefficient to code "get executable bit", "get writable bit", etc... it's easier to just have a generic "get all bits", then filter for the one(s) you really need. so it's `function is_executable(x) { return extract_relevant_bits(stat($x)) }` – Marc B Aug 08 '16 at 15:23