1

Say someone has a shell script named Foo.sh in his current working directory. It reads like

#!/bin/bash
#some scripts below

In order to run the script by typing "./Foo.sh", he needs execution permission with it. Instead he can choose to execute the script by simply do "bash Foo.sh", passing the script as an argument to program bash. In the latter case, he only needs read permission.

This seems permission inversion to me, that is, a user can execute an executable that he has no permission to execute.

My question is:

  1. Is this an intentional design which has some soundness behind it, or a legacy problem, preserved solely for compatibility reasons?

  2. Does this has some security implications?

  • 1
    Well, if a user has read access to a script, s/he can open the file up and manually type the commands into a shell, so enforcing the execute bit for scripts doesn't accomplish much. – dsstorefile1 Mar 9 '18 at 1:43
  • @dsstorefile a bash script can contain lots of weird stuff, for example, stackoverflow.com/q/18410785/6156470 – John Z. Li Mar 9 '18 at 1:56
  • In that case, nothing prevents the user from copying the binary contents from the script into its own file and executing that. – dsstorefile1 Mar 9 '18 at 2:06
  • @dsstorefile fair point. – John Z. Li Mar 9 '18 at 6:31
2

This is a device of convenience. The shebang line hardcodes the interpreter into the script. Beside convenience, it's also informative, the same way as the file extension. You can still run it with any other interpreter:

bash script.undefined

or

sh script.undefined

or possibly

perl script.undefined

etc.

Security-wise, it's the same thing. In either case the file is read and executed with the effective user ID of the active user. The sticky bit has no effect for interpreted languages, but that's another story. (In fact, this bit is important for security implications.)

  • 2
    Be careful about perl. It will try to run the script using the interpreter given in the shebang, if the shebang doesn't use perl. askubuntu.com/a/850575/158442 – muru Mar 9 '18 at 2:00
  • 1
    See also things like /lib64/ld-linux-x86-64.so.2 /bin/ls (on Ubuntu). – Kusalananda Mar 9 '18 at 8:01
0

Technically it works as it is supposed to be. When you run

./foo.sh

You are running foo.sh program (With help of shebang)

But when your run

bash foo.sh

technically you are running bash program (/bin/bash or /usr/bin/bash).

If you are concerned about security. Imagine user has read access of foo.sh and user copies content of foo.sh to bar.sh which he/she has execute access. So in all the cases if user can read .sh files he/she can execute it easily.

0

It's just a consequence of the old saying that "one man's data is an other man's program". Computers are built based on the Von-Neumann-Architecture, and this means that there is nothing inherent in files which say "this is an executable and the other one is not". Any prose text you write can act as a program when interpreted by a suitable interpreter.

Hence, if a file contains information which needs to be concealed, you need to read-protect it. Execution protection does not help. Even if you have a compiled program, which you execute-protect, but not read-protect, I can easily run it. I just need to copy it, set the execute permission on the copy, and I'm done.

So, if you want safety, you have to remove read permission, not execute permission, from the file, and from the directory where the file is located.

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.