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; }
signature.asc
Description: Digital signature