Description
MODSEC-164: A faulty backend is able to segfault a reverse proxy with modsecurity, SecResponseBodyAccess On and mod_mem_cache enabled.
Faulty response:
HTTP/1.1 301 Moved Permanently
Date: Mon, 14 Jun 2010 08:45:26 GMT
Server: netcat
Content-Type: text/html; charset=UTF-8
Content-Length: 10
Location: http://www.example.com/target
Connection: close
Note that the response announces a Response Body but none is transferred.
This is the apache error-log:
[Tue Jun 15 15:25:23 2010] [debug] mod_proxy_http.c(1732): proxy: start body send
[Tue Jun 15 15:25:27 2010] [debug] mod_proxy_http.c(1836): proxy: end body send
[Tue Jun 15 15:25:27 2010] [debug] proxy_util.c(2029): proxy: HTTP: has released connection for (127.0.0.1)
[Tue Jun 15 15:25:27 2010] [debug] mod_cache.c(705): cache: Caching url: /proxy
[Tue Jun 15 15:25:27 2010] [debug] mod_cache.c(711): cache: Removing CACHE_REMOVE_URL filter.
[Tue Jun 15 15:25:27 2010] [debug] mod_mem_cache.c(752): mem_cache: URL http://127.0.0.1:8000/proxy? didn't receive complete response, not caching
[Tue Jun 15 15:25:27 2010] [debug] mod_cache.c(912): (20014)Internal error: cache: store_body failed
2-3 seconds afterwards, the server process crashes. Note that the root process does not crash. But he is no longer able to replace a killed child process.
Details:
Apache compilation on debian:
$ ./configure --prefix=/data/apache-2.2.15 --enable-mods-shared=all --enable-proxy --enable-proxy-http --enable-cache --enable-mem-cache --with-included-apr
ModSecurity compilation on debian:
$ ./configure --with-apxs=/data/folinic/apache/apache-2.2.15/bin/apxs --with-apu=/data/apache-2.2.15/bin/apu-1-config
Apache config:
ServerName www.example.com
ServerRoot /data/apache-2.2.15
User www-data
Group www-data
PidFile /tmp/httpd.pid
LockFile /tmp/httpd.lock
Listen 127.0.0.1:8000
ErrorLog /tmp/error.log
LogLevel debug
LoadModule unique_id_module modules/mod_unique_id.so
LoadModule security2_module modules/mod_security2.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule cache_module modules/mod_cache.so
LoadModule mem_cache_module modules/mod_mem_cache.so
SecRuleEngine On
SecResponseBodyAccess On
CacheEnable mem /
<VirtualHost 127.0.0.1:8000>
ErrorLog /tmp/error.log
ProxyPass /proxy http://127.0.0.1:7030/
Backend Configuration:
/bin/nc -l -s 127.0.0.1 -p 7030 < /tmp/bogus_response
-> see above for the response and be sure to kill netcat by hand when the response has been written out (which is immediately after connection).
Request crashing the server:
curl -v http://127.0.0.1:8000/proxy
This bug does not appear with Apache 2.2.14. But there has been a lot of coding in mod_cache/mod_mem_cache between 2.2.14 and 2.2.15.
I am not sure this is a bug in ModSecurity. Note that disabling response body access in ModSecurity makes the error go away, while the
error message above persists. So Mod_mem_cache is able to deal with the bogus response, while ModSecurity seems to have apache crash.