In Linux, file permissions determine the levels of privilege for file owners and everyone else. It’s important to make sure any web-facing files have their permissions set correctly, so that a compromised process can’t write to places it shouldn’t.

What Are File Permissions?

File permissions track the permissions for three different groups. Each group is represented by three bits:

r: The “Read” permission allows a process to read the contents of that file into memory. w: The “Write” permission gives a process access to overwrite the physical location on disk where that file is stored. x: The “Execute” permission is for programs and allows that file to be executed.

In the terminal, permissions are displayed like so:

The first “d” signifies whether the file is a directory. The first group of three is for the file owner. In this case, the file owner has full read, write, and execution access. The next group of three is “group owners,” which denotes the access rights for the group the file belongs to, in this case, read only. The next group is everyone else, which is read only.

Generally, files with open “everyone” permissions are not very secure. You will want to make sure the last group is set to read-only or no access for most files.

Under the hood, these are stored in binary, with each permission representing a bit. For example, rw- is 110 in binary, which is 6 in decimal. So, the permission string:

…could be stored as “764.” File permissions will often be referred to this way; “777” denotes full access, “700” is private, “644” is read-only. Technically, this is known as octal, not decimal, because there are eight possible values for each digit.

For directories, the permissions use the same characters, but are a bit different:

r: List permission. Allows the directory to be opened, and allows the use of ls. Requires the x attribute to be set. w: Write permission. Allows creation of new files, deletion of file, and renaming files. Does not prevent changing the contents of existing write-enabled files within the directory. x: Enterability. Allows the use of cd. This is respected system wide, and will prevent the folder from being opened in a GUI file explorer.

On some systems, particularly macOS, there may be a “@” after the file permission string. This means the file has extended attributes, which you can check with ls -l@. For example, the com.apple.quarantine attribute is assigned to executables that have not been opened yet, so that Gatekeeper can block you from double-clicking it, force you to right-click > open and then needlessly prompt you if you’re really sure you want to open it.

What Are File Owners and Groups?

The file owner is just a particular user, but users in Unix systems don’t work the same way they do in Windows. Unix can have different users for individual processes like mysql and nginx. This can make permissions very detailed; for example, an instance of MySQL running under the mysql user can access its own database, but the nginx user cannot.

User groups work in a similar manner but support having multiple users with the same permissions. Users can be added and removed from the group, and they’re optional for setting file permissions.

How to Check File Permissions of Directories

You can view file and directory permissions by running ls -l in your terminal. File permissions are displayed on the far right:

If you want to display the file permissions for a specific file or directory, you’ll need to pipe the ls output to grep:

Note that the current folder and parent folder have their permissions displayed as . and .. when using the -a flag. However, even this only displays two levels of permissions. To display permissions for every parent folder, you’ll need to use the namei command:

This command may not be installed on every Linux distribution. On macOS, you’ll have to install it from brew.

To search for individual files within those folders that may have errant permissions, you can use the find command with the -perm flag:

This searches recursively, and may take some time if you’re running it on the root directory.

How to Change File Permissions and Ownership

Changing file permissions is simple with the chmod command:

You can also add permissions without specifying a full permission string. This is a shortcut, but can save some time. For example, if you can’t open a script file, you can add permission for the owner to execute with:

This adds the execute (x) permission for the current owner (u, for “user”).

Changing owners works similarly with the chown command:

The “:group” is optional. Both chmod and chown can be run recursively on directories, to change file permissions for everything within those directories. To do this, use the uppercase -R flag:

You can also use chmod as the -exec option for find, which lets you change file permissions throughout the system. For example, this command will find files that have open write permissions, and set them to read-only: