Package: boa
Version: 0.94.14rc21-0.2
Severity: important
Tags: security

CVE-2009-4496 describes a multi-step vulnerability whereby Boa does not escape
nonprintable characters from the request when writing to its error log.  While
not a vulnerability in itself, this provides a vector for an attacker seeking
to exploit weaknesses in terminal emulators used by site administrators who
may display the log.  The particular attacker-controllable data being logged
is in the local path translation of the request URL.  A sample exploit and
further details are available here:

        http://www.ush.it/team/ush/hack_httpd_escape/adv.txt

The Debian security team regards this class of vulnerabiliy as primarily a
security issue in the vulnerable terminals, rather than the webservers writing
the logs.  We do not plan to release security updates to the webservers.
Nonetheless, we do suggest patching the affected webservers so as to mitigate
this particular vector against possible future emulator weaknesses.

I'm attaching a patch which corrects the problem in Boa by applying C-style
escaping of nonprintable characters to strings before logging.  Please apply
it, or an equivalent fix.


Devin
-- 
Devin  \ aqua(at)devin.com, IRC:Requiem; http://www.devin.com
Carraway \ 1024D/E9ABFCD2: 13E7 199E DD1E 65F0 8905 2E43 5395 CA0D E9AB FCD2
diff -aruN boa-0.94.14rc21.orig/src/log.c boa-0.94.14rc21.fixed/src/log.c
--- boa-0.94.14rc21.orig/src/log.c	2005-02-22 06:11:29.000000000 -0800
+++ boa-0.94.14rc21.fixed/src/log.c	2009-12-31 01:27:01.000000000 -0800
@@ -156,6 +156,29 @@
            (req->header_user_agent ? req->header_user_agent : "-"));
 }
 
+static char *escape_pathname(const char *inp)
+{
+    char *escaped, *c;
+
+    if (!inp) {
+        return NULL;
+    }
+    escaped = (char *)malloc(1 + strlen(inp) * 4);
+    if (escaped == NULL) {
+    	perror("malloc");
+	return NULL;
+    }
+    for (c = escaped; *inp; inp++) {
+        if (needs_escape((unsigned int)*inp)) {
+            c += sprintf(c, "\\x%02x", (unsigned int)*inp);
+        } else {
+            *(c++) = *inp;
+        }
+    }
+    *(c++) = '\0';
+    return escaped;
+}
+
 /*
  * Name: log_error_doc
  *
@@ -173,26 +196,29 @@
 void log_error_doc(request * req)
 {
     int errno_save = errno;
+    char *escaped_pathname;
 
     if (virtualhost) {
         fprintf(stderr, "%s ", req->local_ip_addr);
     } else if (vhost_root) {
         fprintf(stderr, "%s ", (req->host ? req->host : "(null)"));
     }
+    escaped_pathname = escape_pathname(req->pathname);
     if (vhost_root) {
         fprintf(stderr, "%s - - %srequest [%s] \"%s\" (\"%s\"): ",
                 req->remote_ip_addr,
                 get_commonlog_time(),
                 (req->header_host ? req->header_host : "(null)"),
                 (req->logline ? req->logline : "(null)"),
-                (req->pathname ? req->pathname : "(null)"));
+                (escaped_pathname ? escaped_pathname : "(null)"));
     } else {
         fprintf(stderr, "%s - - %srequest \"%s\" (\"%s\"): ",
                 req->remote_ip_addr,
                 get_commonlog_time(),
                 (req->logline ? req->logline : "(null)"),
-                (req->pathname ? req->pathname : "(null)"));
+                (escaped_pathname ? escaped_pathname : "(null)"));
     }
+    free(escaped_pathname);
 
     errno = errno_save;
 }

Attachment: signature.asc
Description: Digital signature

Reply via email to