bash Permissions – How Users Execute File Without Permission

bashcommand lineexecutablepermissionsusers

I created a Bash script which echoes "Hello World". I also created a test user, bob, using adduser.

Nobody has permission to execute that file as denoted by ls:

$ ls -l hello.sh 
-rw-r--r-- 1 george george 19 Mai 29 13:06 hello.sh

As we can see from the above the file's owner is george where he has only read and write access but no execute access. But logged in as george I am able to execute the script directly:

$ . hello.sh 
Hello World

To make matters worse, I log in as bob, where I have only read permission, but I am still able to execute the file:

$ su bob
Password: 
$ . /home/george/testdir/hello.sh 
Hello World

What's going on?

Best Answer

In your examples, you are not executing the files, but sourcing them.

Executing would be via

$ ./hello.sh

and for that, execution permission is necessary. In this case a sub-shell is opened in which the commands of the script file are executed.

Sourcing, i.e.

$ . hello.sh

(with a space in between) only reads the file, and the shell from which you have called the . hello.sh command then executes the commands directly as read, i.e. without opening a sub-shell. As the file is only read, the read permission is sufficient for the operation. (Also note that stating the script filename like that invokes a PATH search, so if there is another hello.sh in your PATH that will be sourced! Use explicit paths, as in . ./hello.sh to ensure you source "the right one".)

If you want to prevent that from happening, you have to remove the read permission, too, for any user who is not supposed to be using the script. This is reasonable anyway if you are really concerned about unauthorized use of the script, since

  • non-authorizeded users could easily bypass the missing execution permission by simply copy-and-pasting the script content into a new file to which they could give themselves execute permissions, and
  • as noted by Kusalananda, otherwise an unauthorized user could still comfortably use the script by calling it via
    sh ./hello.sh
    
    instead of
    ./hello.sh
    
    because this also only requires read permissions on the script file (see this answer e.g.).

As a general note, keep in mind that there are subtle differences between sourcing and executing a script (see this question e.g.).

Related Question