mod_mysql_vhost SQL injection and path traversal
==================================================
CVE-2014-2323 [1] was assigned to SQL injection bug.
CVE-2014-2324 [2] was assigned to the path traversal bug.
The fix for CVE-2014-2323 also fixes CVE-2014-2324.
Description
-------------
Jann Horn reported a MySQL injection vulnerability through
a combination of two bugs:
* request_check_hostname is too lax: it allows any host names starting with
[ipv6-address] followed by anything but a colon, for example:
GET /etc/passwd HTTP/1.1
Host: [::1]' UNION SELECT '/
* mod_mysql_vhost doesn't perform any quoting; it just replaces ? in the
query string with the hostname.
mod_evhost and mod_simple_vhost are vulnerable in a limited way too; a
pattern: evhost.path-pattern = "/var/www/%0/" with a host "[]/../../../"
leads to document root of "/var/www/[]/../../../", but as "/var/www/[]"
usually doesn't exists this fails (this might depend on the operating
system in use).
If there exist directories like "/var/www/[...]" for IPv6 addresses as
host names (or a user can create them) mod_evhost and mod_simple_vhost
are vulnerable too.
mod_status, mod_webdav and a global redirect handler use the host name
without escaping too; in these cases the client just gets the broken data
back - the attacker doesn't gain anything here.
Detailed analysis
-------------------
Quoting the report from Jann Horn:
> Have a look at this special case of request_check_hostname in request.c:
(See [3])
> So, when the hostname starts with a '[', only this block of code validates the
> user-supplied hostname. First, the code incorrectly commented with
> "/* check portnumber */" checks that until ']', only something resembling an
> IPv6 address can appear. Then it is checked that the hostname is correctly
> terminated with a ']'. But then, it only validates that a correct port number
> follows if the next char is a ':'. If the next char is anything else, the rest
> of the Host header is not subjected to any kind of check before being stored
> into con->uri.authority.
> In a lighttpd without anything special, this already means that an attacker can
> sneak spaces into the logfile, potentially confusing logfile parsers. However,
> it gets really interesting when the server uses mod_mysql_vhost (not
> mod_simple_vhost or mod_evhost): con->uri.authority is inserted into an SQL
> query without any escaping, allowing the attacker to control what the database
> responds with - and the response of the database is then taken as document
> root. Therefore, an attacker can change the document root to / for his request
> and thereby effectively perform directory traversal.
If one wants to search for uses of con->uri.authority one should also search
for con->server_name.
Affected versions
-------------------
All versions up to and including 1.4.34.
Patch
-------
See [4] (simple patch) or [5] (svn commit including test cases).
Fixed in
----------
1.4.x: http://redmine.lighttpd.net/projects/lighttpd/repository/revisions/2959
1.4.35: http://www.lighttpd.net/2014/3/12/1.4.35/
Solutions or workaround
-------------------------
* Disable mod_mysql_vhost.
* Don't use mod_evhost or mod_simple_vhost for IPv6 addresses as host names
(i.e. don't have and don't allow creation of "[...]" directories in the
base directories)
References
------------
[1] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2323 SQL injection
[1] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2324 path traversal
[3] http://git.lighttpd.net/lighttpd/lighttpd-1.x.git/tree/src/request.c?id=lighttpd-1.4.34#n41
[4] http://download.lighttpd.net/lighttpd/security/lighttpd-1.4.34_fix_mysql_injection.patch
[5] http://redmine.lighttpd.net/projects/lighttpd/repository/revisions/2959/diff/
GPG signatures
----------------
* http://download.lighttpd.net/lighttpd/security/lighttpd-1.4.34_fix_mysql_injection.patch.asc
* http://download.lighttpd.net/lighttpd/security/lighttpd_sa_2014_01.txt.asc