Serving websites from svn checkout considered harmful
Serving from a working copy
A simple way to update sites is to serve them from Subversion working copies. Checkout the code on the server, develop and commit changes, then svn update
the server when you’re ready to release.
Security concerns
There’s a potential security problem with this. Subversion keeps track of meta-data and original versions of files by storing them in .svn
directories in the working copy. If your web server allows requests that include these .svn
directories, anything within them could be served to whoever requests it.
Requests would look like:
http://example.com/stuff/.svn/entries
http://example.com/stuff/.svn/text-base/page.php.svn-base
http://example.com/stuff/.svn/text-base/settings.py.svn-base
The first one would reveal some meta-data about your project, such as file paths, repository urls and usernames.
The second one may be interpreted as a PHP script, in which case there’s little risk. Or it may return the PHP source file, which is a much bigger risk.
The third one (assumed to be a Django project) should never happen. The request can only be for files within the web server’s document root. Code itself doesn’t need to be there, only media files do.
Alternatives
Instead of serving sites from a working copy, you can use svn export
to get a “clean” copy of the site which does not include .svn
directories. If you svn export
from the repository, you must export the complete site, rather than just update the changed files, which could be a lot more data.
However, you can svn export
from a working copy on the server. It’s still a complete export, but you don’t have to trouble the repository, so it’s typically much quicker.
An alternative is to update a working copy which is stored on the server, but not in the web document root, then use rsync
or some file copying to update the “clean” copy in the web document root. In this case, only changed files are affected.
Protection through web server config
If you do serve from working copies, you should configure the web server to block all requests which include .svn
in the url. Here’s how to do it for some popular web servers:
Apache
<LocationMatch ".*\.svn.*"> Order allow,deny Deny from all </LocationMatch>
Lighttpd
$HTTP["url"] =~ ".*\.svn.*" { url.access-deny = ("") }
Nginx
Using the location
directive which must appear in the context of server
.
server {
location ~ \.svn { deny all; }
...
}