4

I have a zip file containing lot of files and directories for a certain application which should be running on Linux. Some files needs to be set as executable, but the zip file format afaik does not preserve execution rights.

I need to manually set the execution right on files after extracting the archive and (I am getting to it) my question is:

If I do not know which files need to be executable, is it good idea to add the execution permission recursively to the whole directory? Can it posses any security risks? Is anyone aware of any other problems it may cause?

L.R.
  • 293

3 Answers3

7

It's not pretty or elegant, but adding the executable bit to a file that isn't any kind of executable the OS knows what to do with isn't harmful -- if you try you'll likely just get cannot execute binary file

One potential risk would be text files if somehow the first few words turn out to be valid commands in the shell, but that's hard to predict (if unlikely).

I'd personally err on the side of caution and keep everything non-executable, then write a quick script to sort through all files with the file command and flip the executable bit if it's recognized as a script or an ELF binary -- exact code left as an exercise to the reader.

  • This is a nice trick with the file command. I will try that and let you know how did it end up. – L.R. Nov 11 '11 at 12:35
  • 1
    You can also play it smart and tell find to exclude anything with an 'obvious' extension from the search - .jpg, .png, .txt and so on don't even need to be looked at. Depending on how big a tree you're searching through, that might significantly optimize the search... – Shadur-don't-feed-the-AI Nov 11 '11 at 14:12
3

Simple answer - yes, it can pose security risks - but these are entirely dependent on the specific access control requirements for the files and directories involved.

Your best bet is to ask the application owner/developer/etc whether there are any files or directories which require permissions to be enforced as well as whether there are any which need to be set executable. It should be their call, not yours, so I would avoid taking the responsibility if you don't know the application requirements!

It may well be that the numbers are low, so it becomes a simple process. YMMV

Rory Alsop
  • 2,063
  • 15
  • 30
  • Your best bet is to ask the application owner I did that and I was told that I should set executable bit for all files. I do not know if they know enough about that :) That's why I am asking more experienced people here. – L.R. Nov 11 '11 at 12:34
  • 1
    The problem is that we can only make assumptions as we don't know the application. One option is to keep everything non-exec and see what breaks - I know, not practical, but I have used similar to help persuade app owners to understand what their app does (for example firewalling Tivoli until their guys could figure out what ports they needed :-) – Rory Alsop Nov 11 '11 at 12:38
2

There isn't any direct security risk with making a file executable unless it's setuid or setgid. Of course, there's the indirect risk that something you expect to be inert — some data file that you'd normally open in an application — can also be executed directly on your system with nefarious consequences. For example, if you have a file called README that actually contains a rootkit program, opening it in a text editor is safe, but you'd better not execute it.

A reasonable heuristic to recognize files that are meant to be executable is to look at their first few bytes and recognize executable signatures. This is a matter of convenience rather than security, but if you're willing to make all files executable anyway, it means you don't have a security concern but a usability concern anyway. Here's a possible heuristic:

for x in *; do
  case $(file - <"$x") in
    *executable*) chmod +x -- "$x";;
  esac
done

Here's another heuristic which should differ only in corner cases ($'\177' is ksh/bash/zsh syntax, replace it by a literal character 0177 = 127 = 0x7f in other shells).

for x in *; do
  case $(head -c 4 <"$x") in
    '#!'*|$'\177'ELF) chmod +x -- "$x";;
  esac
done

In both cases, just because a file is recognized as executable doesn't mean you can execute it on your system; for example a binary for the wrong processor architecture will be happily made executable. Here's a different approach that makes all scripts executable, but dynamically linked binaries only if they're for the right architecture and you have the required libraries, and misses statically linked binaries altogether.

for x in *; do
  case $(head -c 2 <"$x") in
    '#!') chmod +x -- "$x";;
    *) if ldd -- "$x" >/dev/null 2>/dev/null; then chmod +x "$x"; fi;;
  esac
done
  • I found the other answers perfectly OK as well, but this one is the most elaborated :) – L.R. Nov 16 '11 at 09:19