03 Apr Do You Blindly Run ‘chmod a+x’ On Your macOS Scripts? You Probably Shouldn’t Be.
Have you ever copied a script from the Internet and wondered why the last thing you’re told to do is to run the following command in terminal?
chmod a+x /path/to/your/script.sh
Most likely the script author reminded you the script must have execute permissions. What this means, you have no idea, right? You just do it because you’ve tried to skip it and found the script wouldn’t run.
I know this, because I too have done it. At times I blindly follow directions wishing I had some background info as to why. All too often I can’t find out the why, so I just proceed with what is being asked so I can get my job done.
Well, today, I want to discuss macOS file permissions and why you should be more specific when specifying who can execute the scripts you create.
What are file permissions?
Every file and folder within macOS has a set of permissions assigned to them. These permissions control who can read, write and execute the given file or within the folder. Permissions are assigned to three distinct objects, the owner for the file/folder, the group(s) assigned to the file/folder and the “other” bucket containing all other users and groups not previously specified.
How are file permissions designated?
Within macOS, permissions can be assigned to a filer or folder using letters or numbers. When using letters, or the symbolic notation, you use r for read, w for write, x for execute, or a combination of some or all of these options and apply them to the user, group, and other ownership objects.
If you prefer to use numbers rather than letters, the numerical notation can be used. 0 is for no permission, 1 execute, 2 write, 3 write and execute, 4 read, 5 read and execute, 6 read and write and 7 for read, write and execute.
Below is a diagram illustrating how the symbolic and numerical notations relate.
How do I know what permission have been assigned to a file or folder?
The easiest way to see the permissions for all files in a given folder, is to open Terminal, browse to your specific folder and type:
Typing ‘ls – l’ (L’s not 1’s) in Terminal will show the permissions for the user, group and then everyone else on a per file basis within the folder specified in Terminal. The first bit denotes D for Directory or – for file. The next three bits specify the user’s permissions, the fourth, fifth and sixth bits specify the group’s permissions and the last three identify the permissions for the other object.
In my example screenshot above, I browsed to the directory ~/Documents and typed ls -l. This returned three files and one directory: HostHame.sh, Test, example.txt, and untitled text.txt. Below is a diagram of the permissions applied to each file’s and folder’s user, groups, and other objects.
As can be seen above, HostName.sh and Test have read/write/execute for the user and read/execute permissions for all group and everyone else, but example.txt and untitled text.txt do not have any permissions at all applied.
How do I change the file permissions?
You can change the read or write permissions for a user or a group via the Get Info panel in the Finder GUI.
For more specific permission changes, you’ll need to use Terminal. macOS has a built in function called ‘chmod,’ which allows you to modify the file permissions as specified by the mode operand.
Notice in the image to the above how I have two files, example.txt and untitled text.txt with no permissions (———-) applied.
If, on the file example.txt, I just run the oft asked command of:
chmod a+x example.txt
Then all I do is augment the existing permissions of “———” with execute permissions for all objects, changing it to ‘—x–x–x’.
For your understanding, the ‘a’ in the chmod command is short for all and is selecting the user, group, and other objects. The + indicates you want to add to the file permissions and x, as we discussed previously, indicates you want to give the file execute rights for the specified objects – in our case for everyone (user, groups and others).
I’m now done, right? My script can now be executed, so it’s time for me to move on.
Well, maybe not so fast. There is a downside to just blindly running this command ‘chmod a+x example.txt’.
First off, we’ve just given anyone and everyone the ability to execute this script. Even if the person who stumbles across this script can’t see what’s in it, they can blindly execute it. If you’re security conscious at all, this should be concerning to you.
Furthermore, if anyone and everyone can also write to this file and make nefarious changes to the script, we could get into some serious trouble. This is the second reason running ‘chmod a+x’ is not a good idea.
In our scenario above, we know the example.txt file has ‘—x–x–x’ permissions. However, we only know that because we ran the command ‘ls -l’ prior to the chmod a+x command. Generally, this check on the file permission state is not done before augmenting the file with execute permissions. That means, that more often than not, we don’t specifically know who can read and write to the file, we just know everyone can execute it. As Apple administrators, we need to be more cautious.
What should I do instead of running chmod a+x?
OK, so rather than just adding execute permissions to the file, it would be far better to specify specifically what user and groups can read, write and or execute the file. For security reasons, this is a superior approach.
Using the numerical notation, in Terminal, I can assign my current user as having read, write, and execute permissions, with the specified groups and other objects as having read and execute permissions for the file untitled text.txt by running this command instead:
chmod 755 untitled\ text.txt
The 7 represents read/write/execute for the user, the first 5 denotes read/execute for the groups and the last 5 value specifies all other groups and unlike the chmod a+x command, chmod 755 throws out all of the old permissions and sets them anew as specified.
While everyone and anyone still has access to execute this script, we’ve conscientiously set it and we’ve protected ourselves by removing the ability for any changes to be made to the file by anyone except for the specific file owner.
By the way, if I wanted to use the symbolic notation to accomplish what the numerical notation of 755 did, I’d have to run:
I prefer the numerical, as it’s easier for me, but both work equally as well.
Now, depending on what your script does and how it’s going to be utilized, you may need to further restrict execute permissions. To be more security consciences, I may choose to run:
chmod 750 untitled\ text.txt
chmod 700 untitled\ text.txt
In the end, it doesn’t matter what you set it to as long as you understand why you’re providing a file with the specific permissions you chose.
Be safe. Be secure. Don’t just blindly add execute permissions.