1. Introduction
Some directories in Linux are accessible by everyone, i.e., all security principals or, put simply, the world. This means such directories provide at least read permissions globally. However, it’s usually much rare to see a world-writable object, let alone a whole directory. Yet, there are such cases.
In this tutorial, we’ll go over the default world-writable directories of a fresh Linux system and the concept of fully-open permissions in general. First, we discuss the common standard of the Linux base directory structure. Next, we explore the default permissions for most of that top-level hierarchy. After that, we talk about the security of world-writable directories. Later, we enumerate default Linux paths with fully-open permissions. Finally, we check ways to find and identify all such directories.
For brevity, we use the terms world-writable and fully open more or less interchangeably.
We tested the code in this tutorial on Debian 11 (Bullseye) with GNU Bash 5.1.4. It should work in most POSIX-compliant environments unless otherwise specified.
2. Filesystem Hierarchy Standard (FHS)
Linux follows the UNIX Filesystem Hierarchy Standard (FHS). Among others, the standard defines areas of the rootfs root filesystem, so users and applications can predict the correct location of given files and directories:
+-----------------------------------------------------------+
| Directory | Description |
|-----------+-----------------------------------------------|
| bin | essential command binaries |
| boot | boot loader static files |
| dev | device files |
| etc | host-specific system configuration |
| lib | essential shared libraries and kernel modules |
| media | mount point for removable media |
| mnt | mount point for temporarily filesystem mounts |
| opt | add-on application software packages |
| sbin | essential system binaries |
| srv | data for provided services |
| tmp | temporary files |
| usr | secondary hierarchy |
| var | variable data |
+-----------------------------------------------------------+
Notably, some of these directories, like /media, /mnt, srv, and /usr, can include a further subhierarchy. However, that may not comply with any FHS guidelines.
Still, there are FHS recommendations for the top-level or root paths. For instance, /bin and /sbin utilities usually contain specific executables.
Of course, this means they should be accessible to most users and have the proper permissions set.
3. FHS Permissions
In general, the permissions of top-level FHS directories stem from their function. Let’s explore the paths with ls and its [-l]ong listing and [-d]irectory flags:
$ ls -ld \
/bin /boot /dev /etc /lib \
/media /mnt /opt /sbin /srv \
/tmp /usr /var
lrwxrwxrwx 1 root root 7 Oct 10 2022 /bin -> usr/bin
drwxr-xr-x 3 root root 4096 Apr 4 11:10 /boot
drwxr-xr-x 16 root root 3330 Apr 4 11:11 /dev
drwxr-xr-x 115 root root 12222 May 5 15:15 /etc
lrwxrwxrwx 1 root root 7 Oct 10 2022 /lib -> usr/lib
drwxr-xr-x 3 root root 4096 Oct 10 2022 /media
drwxr-xr-x 6 root root 2660010 Apr 04 04:04 /mnt
drwxr-xr-x 2 root root 4096 Oct 10 2022 /opt
lrwxrwxrwx 1 root root 8 Oct 10 2022 /sbin -> usr/sbin
drwxr-xr-x 3 root root 4096 Mar 3 03:33 /srv
drwxrwxrwt 12 root root 1024 May 5 05:55 /tmp
drwxr-xr-x 14 root root 4096 Oct 10 2022 /usr
drwxr-xr-x 14 root root 4096 Apr 4 04:40 /var
As we can see, some of the above paths are links to /usr subdirectories. Since permissions of symbolic links don’t matter, we can resolve their targets:
$ ls -ld /usr/bin /usr/lib /usr/sbin
drwxr-xr-x 2 root root 55200 May 5 01:01 /usr/bin
drwxr-xr-x 78 root root 4096 Apr 4 02:20 /usr/lib
drwxr-xr-x 2 root root 20666 Apr 4 02:25 /usr/sbin
Evidently, all of this default structure is owned by root. Following the links, we can see most permissions are also the same: rwxr-xr-x. In other words, only the owner (root) can write to almost all root FHS directories.
Still, there are exceptions.
4. Security of World-Writable Paths
Since anyone can create files in fully-open directories, applications are mainly responsible for several points:
- avoid overfilling the filesystem
- securing own filesystem objects with the proper permissions
- attempting filesystem object creation with overlapping names
- executing foreign files
While overfilling can be limited to a partition created for a specific purpose, that’s not always the case. Further, file and directory creation is usually very important in this context. For example, we can use the open() system call with O_EXCL to ensure we don’t replace files. In specific instances, mktemp can also be helpful.
Still, we should definitely protect sensitive content from open permissions, as failing to do so can have severe consequences.
Finally, the sticky bit usually prevents the deletion of a world-writable directory and files within it with a few exceptions:
- owner of the file
- owner of the directory
- root
Further, we can recognize this setting as a four-digit mode that starts with 1, e.g., 1666. When it comes to the output of ls, a t takes the place of the last executable bit character (normally x or –) to indicate the sticky bit.
For instance, a fully-open directory with the sticky bit would have drwxrwxrwt as the first column of ls in long list mode.
5. World-Writable FHS Paths
Although it’s relatively uncommon in general, some directories do have open permissions that allow everybody to write to them.
Still, the control over these exceptional paths is often limited because they usually have the sticky bit set.
5.1. Temporary Directories
As expected, the /tmp directory has a different set of permissions from the others at the root level:
$ ls -ld /tmp
drwxrwxrwt 12 root root 1024 May 5 05:55 /tmp
Naturally, the temporary directory has these rwxrwxrwt open permissions to serve all security principals. So, /tmp is world-writable. That means, by extension, /var/tmp and /usr/tmp may also have the same permissions:
$ ls -ld /var/tmp/
drwxrwxrwt 4 root root 4096 May 9 00:00 /var/tmp/
However, if they even exist, /var/tmp and /usr/tmp are sometimes only symbolic links to /tmp.
5.2. /dev/shm and /dev/mqueue
The /dev/shm directory can provide inter-process data sharing or fast storage for files that a reboot would delete:
$ ls -ld /dev/shm
drwxrwxrwt 2 root root 40 Apr 04 08:08 /dev/shm
Similarly, the /dev/mqueue POSIX message queue filesystem enables any principal to communicate with another:
$ ls -ld /dev/mqueue
drwxrwxrwt 2 root root 40 Apr 20 04:20 /dev/mqueue
As such, both /dev/shm and /dev/mqueue have world-writable permissions along with the sticky bit. In fact, we can see these as particular cases of a temporary directory.
5.3. Lock File Directories
Locks are files that ensure there is only a single instance of a given process. They usually reside in the /var/lock directory:
$ ls -ld /var/lock
lrwxrwxrwx 1 root root 9 Oct 10 2022 /var/lock -> /run/lock
$ ls -ld /run/lock
drwxrwxrwt 5 root root 100 Apr 04 14:00 /run/lock
Although it’s a symbolic link, following that reveals a lock directory, /run/lock in this case, with fully open permissions and the sticky bit set. Since locks are a common mechanism, these settings are to be expected. Again, this is also a specific-purpose temporary directory.
5.4. /var/* and /var/spool/*
Other temporary paths with a specific purpose include so-called spooler directories. They are mainly responsible for handling printing tasks but can also be used for mail and similar queues.
Since such activities are common among users and data only resides in the paths temporarily, spooler directories can be world-writable as well:
$ ls -ld /var/mail/
drwxrwsr-x 2 root mail 4096 Apr 16 10:17 /var/mail/
$ ls -ld /var/spool/
drwxr-xr-x 9 root root 4096 Apr 5 08:18 /var/spool/
$ ls -l /var/spool/
total 28
drwxr-xr-x 2 root root 4096 Oct 10 2022 anacron
drwxr-xr-x 5 root root 4096 Apr 4 18:18 cron
drwx--x--- 3 root lp 4096 Jan 01 01:10 cups
[...]
lrwxrwxrwx 1 root root 7 Oct 10 2022 mail -> ../mail
drwx------ 2 root root 4096 May 5 2022 rsyslog
drwxrwxrwt 2 root root 4096 Aug 8 2022 samba
However, even in this instance, the permissions are not open to the world for all except /var/spool/samba, which isn’t a default directory.
6. Identify World-Writable Paths
Although we can reference standards to recognize paths with open permissions, there are also other means to find them.
6.1. World-Writable Filesystems
Because they are part of the random access memory (RAM), tmpfs mounts are often globally accessible.
In fact, some of the directories we already saw are usually of this type:
$ df --output=source,fstype,target
Filesystem Type Mounted on
udev devtmpfs /dev
tmpfs tmpfs /run
/dev/sda1 ext4 /
tmpfs tmpfs /dev/shm
tmpfs tmpfs /run/lock
/dev/sda2 ext4 /home
/dev/sda3 ext4 /tmp
/dev/sda4 ext4 /var
tmpfs tmpfs /run/user/1000
In this case, we see /run/lock and /dev/shm are both tmpfs and world-writable. However, /run doesn’t have open permissions despite being a RAM mount:
$ ls -ld /run
drwxr-xr-x 29 root root 920 May 5 06:56 /run
So, how do we definitively locate world-writable directories?
6.2. Find World-Writable Paths
Of course, outside of what the standards and logic point to, we can have many more world-writable paths. To discover them, we can use the POSIX find:
$ find / -maxdepth 3 -type d -perm -777
/var/tmp
/var/spool/samba
/run/lock
/dev/mqueue
/dev/shm
/tmp
[...]
Looking at a -maxdepth of 3 subdirectories under the / root mount point, we check for objects of the [d]irectory -type that have a [-perm]issions mode of 777. Of course, we can omit the -maxdepth parameter, switch the type to [-f]iles, change up the mode, or even prevent traversing other filesystems via xdev, depending on our needs.
7. Summary
In this article, we discussed fully-open directories in Linux, their behavior, and how to identify them.
In conclusion, although they are only useful in specific cases, world-writable directories exist, so knowing how and when to use them can be critical.