Apache::BlockSymLinks - a PerlAccessHandler for controlling file access via symlinks
# httpd.conf or access.conf <Directory /> Options +FollowSymLinks PerlAccessHandler Apache::BlockSymLinks PerlSetVar SymLinkRules conf/symlinkrules.conf </Directory>
This is a mod_perl PerlAccessHandler that provides an additional level of security on webservers that allow the FollowSymLinks option.
Here's the problem: Apache uses Directory and other containers to designate which parts of the filesystem can and cannot be accessed from the webserver. Unfortunately, it seems that Apache builds the file path from the URI, then checks this path against the known container rules. It does not check the absolute location of the file against those rules. This behavior can be avoided entirely by disallowing the FollowSymLinks option on a given directory, but then all symlinks are thrown out, regardless of where they point.
Apache::BlockSymLinks looks at the filepath of every requested file. This path is resolved to determine its absolute location. If the absolute path cannot be resolved, access is denied. If the absolute path is different from the given path, (i.e. the given path contained one or more symlinks), then the absolute path is checked against a provided access control list. This allows the webmaster to allow the use of symlinks while still ensuring that they cannot be used to read files that are declared off-limits.
<Directory /> Options +FollowSymLinks PerlAccessHandler Apache::BlockSymLinks PerlSetVar SymLinkRules conf/symlinkrules.conf </Directory>
The FollowSymLinks option must be enabled, otherwise any path containing such a link will be denied by Apache regardless of what this handler says.
You can use multiple Directory or Location containers and multiple SymLinkRules files to specify different behavior from links found in different parts of your site.
The SymLinkRules files contains a list of perl regexes that are compared against the absolute filepath to determine whether or not to allow access. The file contains one rule per line, formatted as follows:
The absolute filepath is tested against every rule in the file, in the order they are given. Thus you can use multiple Allow and Deny lines in succession to tailor the access to your needs.
Here is a typical SymLinkRules file:
# This is an example of a SymLinkRules file to protect an # installation located in /usr/local/etc/httpd
# The default rule is to allow everything. Let's reverse that. Deny .*
# allow links into htdocs Allow ^/usr/local/etc/httpd/htdocs
# also allow links into icons Allow ^/usr/local/etc/httpd/icons
# deny links to .cgi files Deny \.cgi$
# deny links to a subdir of htdocs Deny ^/usr/local/etc/httpd/htdocs/private
Charles Brabec (brabec@ncsu.edu)
Version 0.1 2-Feb-2001
Copyright (c) 2001 Charles Brabec. All rights reserved.
This library is free software; you can redistibute it and/or modify it under the same terms as Perl itself.
Significant portions of this code are adapted from the Apache::BlockAgent module as described in Writing Apache Modules with Perl and C by Lincoln Stein and Doug MacEachern.
Apache, File::PathConvert