summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Bühler <stbuehler@web.de>2014-03-12 12:03:55 +0000
committerStefan Bühler <stbuehler@web.de>2014-03-12 12:03:55 +0000
commitd1a23569161148f5acde8d4a6fb78c44284e1853 (patch)
tree9700f07a93257582e7286ea222c83e08982c0a4a
parentefc41b2bb1affbfb33eb6de1071e7ffa3a083a3e (diff)
downloadlighttpd-git-d1a23569161148f5acde8d4a6fb78c44284e1853.tar.gz
fix SQL injection / host name validation (thx Jann Horn)lighttpd-1.4.35
From: Stefan Bühler <stbuehler@web.de> git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2959 152afb58-edef-0310-8abb-c4023f1b3aa9
-rw-r--r--NEWS1
-rw-r--r--src/mod_mysql_vhost.c15
-rw-r--r--src/request.c6
-rwxr-xr-xtests/core-request.t18
4 files changed, 36 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index d288c020..9f4c04ad 100644
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,7 @@ NEWS
* fix unchecked return values from stream_open/stat_cache_get_entry
* [mod_webdav] fix logic error in handling file creation error
* check length of unix domain socket filenames
+ * fix SQL injection / host name validation (thx Jann Horn)
- 1.4.34
* [mod_auth] explicitly link ssl for SHA1 (fixes #2517)
diff --git a/src/mod_mysql_vhost.c b/src/mod_mysql_vhost.c
index 538cfff3..a02ed2c9 100644
--- a/src/mod_mysql_vhost.c
+++ b/src/mod_mysql_vhost.c
@@ -339,6 +339,7 @@ CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
mod_mysql_vhost_patch_connection(srv, con, p);
if (!p->conf.mysql) return HANDLER_GO_ON;
+ if (0 == p->conf.mysql_pre->used) return HANDLER_GO_ON;
/* sets up connection data if not done yet */
c = mod_mysql_vhost_connection_data(srv, con, p_d);
@@ -350,10 +351,20 @@ CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
/* build and run SQL query */
buffer_copy_string_buffer(p->tmp_buf, p->conf.mysql_pre);
if (p->conf.mysql_post->used) {
- buffer_append_string_buffer(p->tmp_buf, con->uri.authority);
+ /* escape the uri.authority */
+ unsigned long to_len;
+
+ /* 'to' has to be 'from_len * 2 + 1' */
+ buffer_prepare_append(p->tmp_buf, (con->uri.authority->used - 1) * 2 + 1);
+
+ to_len = mysql_real_escape_string(p->conf.mysql,
+ p->tmp_buf->ptr + p->tmp_buf->used - 1,
+ con->uri.authority->ptr, con->uri.authority->used - 1);
+ p->tmp_buf->used += to_len;
+
buffer_append_string_buffer(p->tmp_buf, p->conf.mysql_post);
}
- if (mysql_query(p->conf.mysql, p->tmp_buf->ptr)) {
+ if (mysql_real_query(p->conf.mysql, p->tmp_buf->ptr, p->tmp_buf->used - 1)) {
log_error_write(srv, __FILE__, __LINE__, "s", mysql_error(p->conf.mysql));
goto ERR500;
}
diff --git a/src/request.c b/src/request.c
index 5ee072dc..2eb0b0e3 100644
--- a/src/request.c
+++ b/src/request.c
@@ -43,7 +43,7 @@ static int request_check_hostname(server *srv, connection *con, buffer *host) {
char *c = host->ptr + 1;
int colon_cnt = 0;
- /* check portnumber */
+ /* check the address inside [...] */
for (; *c && *c != ']'; c++) {
if (*c == ':') {
if (++colon_cnt > 7) {
@@ -67,6 +67,10 @@ static int request_check_hostname(server *srv, connection *con, buffer *host) {
}
}
}
+ else if ('\0' != *(c+1)) {
+ /* only a port is allowed to follow [...] */
+ return -1;
+ }
return 0;
}
diff --git a/tests/core-request.t b/tests/core-request.t
index a24777f3..6cbfb718 100755
--- a/tests/core-request.t
+++ b/tests/core-request.t
@@ -8,7 +8,7 @@ BEGIN {
use strict;
use IO::Socket;
-use Test::More tests => 36;
+use Test::More tests => 38;
use LightyTest;
my $tf = LightyTest->new();
@@ -198,6 +198,22 @@ EOF
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
ok($tf->handle_http($t) == 0, 'broken IPv4 address - too short');
+$t->{REQUEST} = ( <<EOF
+GET / HTTP/1.0
+Host: [::1]' UNION SELECT '/
+EOF
+ );
+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
+ok($tf->handle_http($t) == 0, 'IPv6 address + SQL injection');
+
+$t->{REQUEST} = ( <<EOF
+GET / HTTP/1.0
+Host: [::1]/../../../
+EOF
+ );
+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
+ok($tf->handle_http($t) == 0, 'IPv6 address + path traversal');
+
## Low-Level Request-Header Parsing - Content-Length