.EXE files are a danger in email attachments, and are usually blocked by Windows email clients. How is this on UNIX/macOS, where executables don't have an extension?

Based on the file data, how do you determine if the file is a program executable (disregarding execute permissions, text-based scripts and files like PDF that indirectly execute a viewer)? Do you simply run file <attachment> and block the file if the result is something like executable?

I'd also like to understand how this works on a low level. I gleaned /usr/share/file/magic/elf. The format is a bit cryptic, but would the following C code reliably detect a Linux executable?

if(strcmp(filedata+0, "\x7fELF") == 0)

What would be the corresponding test for macOS?

3 Answers 3


UNIX alike systems like Linux or MacOS do not run any executable files just because they have a specific extension. To make a file directly executable it needs to have the executable-bit set (chmod +x file) which will not be done done automatically when saving the attachment.

Still, there are many kinds of files which desktop environment on top of Linux (and other OS) like GNOME, KDE,... will automatically open. This is for one based on the file extension similar to what Windows does, i.e. *.doc files will be opened with some office suite, *.pdf with a PDF-Viewer etc. If the extension is missing then most desktop environments will look at the "magic" of the files, i.e. use libmagic to determine the kind of file and open it in the appropriate application. On MacOS there is also an additional mechanisms where the file type and application is includes as attributes (fork) in addition to the file but these information are usually lost when transferring a file through mail (although some archiving programs preserve these attributes).

But, it will NOT automatically mark downloaded files executable and run them. It will also not directly execute shell-script, Perl-Scripts, Python-Scripts etc which don't have the execute-bit explicitly set.

It is though possible that you've downloaded an archive and extracted it. Specific kind of archive formats (like Tar, usually with extensions like *.tar, *.tgz and similar) will include file permissions like the executable bit and these will be usually preserved when extracting the archive. In this case no additional setting of the executable bit is needed and a program could be directly executed.

Thus, withstanding bugs in PDF viewer, Office application or similar applications which are automatically started when you click on a file and withstanding archives, you are generally more safe in Linux since it will not automatically start programs downloaded from somewhere. On the other hand, applications could set a special attribute to files in Windows to specify that the origin of the file is not trusted, which causes Windows to ask for confirmation before executing the file.

If you still want to filter for executable files in attachments you might use libmagic or the libmagic based tool file to detect the file type. Note that these are only heuristics and detection might in theory return a different type, especially for very similar file types (like all the ZIP based office documents, JAR files, ZIP files..). But given that ELF binaries or files with an explicit interpreter definition on top (i.e. #!/usr/bin/python) have a clear structure one can rely on these heuristics for these file types.

Apart from that note that recent Windows versions not only use the file extension to determine what to do with the file. If the file has no extension which is associated with an application it will try to detect the file type without extension similar to how it is done in Linux.

  • How reliable is file when it comes to binary executables (ie. files that are run as their own process, and not opened by a viewer/handler). Will it recognise them 100% correctly? Is it possible to create a rogue executable that file does not recognise as an executable?
    – forthrin
    May 4, 2018 at 16:29
  • 1
    @forthrin: ELF, a.out or Windows binaries should be reliably detected by file and also interpreted files with a #!/some/interpreter on top. I'm not sure about *.desktop files which can also be used to start on double-click but I think these are a desktop-shell speciality anyway and rely on the proper extension. I don't know of any other relevant file types. May 4, 2018 at 21:53
  • 1
    @forthrin Whether or not you can create an ELF binary that file will not recognize, I don't know, but it would be very interesting to find out. I think I'll look into that! ELF handling on Linux is strange. Like the loader ld.so and the kernel's execve() seem to have differing ideas as to what constitutes an ELF file so you can create a file that behaves one way when executed through the loader and another way when executed directly by the kernel.
    – forest
    May 5, 2018 at 22:59

In linux you can use the command "file" that will check the header and tell you the type of file, for example:

lucho@vm1:~$ file engine.so
engine.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=11847fd5591ede794f812fb661f693a940eae73b, not stripped

lucho@vm1:~$ file command
command: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=7b1774a6f6c20faccf2ac8756f7ba07fc857a61d, not stripped

Basically the command file use the library libmagic that is the responsible of identify the file


For windows, it's mostly safe to filter by extension since if it's not a proper extension it will not run (i.e. if the file is named 1.tmp it won't run as that, you'll have to rename it to 1.exe).

For linux, it's best to use header checking of files. That way you will determine if the file is a danger or not. Nothing is advanced about this, it's just standard practice.

In the case of any file content, I'd use clamav's or other anti-virus possibility to block files based on their content (i.e. add #!/bin/bash to the blacklist).

Also, you can block known extensions like .sh, .py, .tar, .gz, .php, .rpm.

  • Could you elaborate on how to do "header checks"? See updated post.
    – forthrin
    May 4, 2018 at 12:03
  • I've updated the answer.
    – Overmind
    May 4, 2018 at 12:49
  • 1
    Extension blocking is never safe, it's always possible to forget certain extensions, or new developments. For example, the list above does not contain a block for self-extracting rar archives which can be as dangerous as executables.
    – Nomad
    May 4, 2018 at 14:14
  • It's as example. You can add as many extensions as you need. I have over 200 windows-based and over 50 linux-based on my implicit reject list of the e-mail server.
    – Overmind
    May 7, 2018 at 7:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.