Take a look at your debug output.  It is catching the 404 text string in the html body of the response and not the HTTP headers.  The quick answer to your situation is that the output filtering of mod_security looks at the body of the response and not the HTTP header info.  One thing that you could try would be to use proxying of some sort with Apache.  I found that when you use the proxy module, mod_security will look at the entire response (headers + body).
 
Give it a try and let me know.
 
--
Ryan C. Barnett
Web Application Security Consortium (WASC) Member
CIS Apache Benchmark Project Lead
SANS Instructor: Securing Apache
GCIA, GCFA, GCIH, GSNA, GCUX, GSEC

 
On 9/2/05, marks mlists <mlist@msnx.de> wrote:

Hello Ivan,

first, it is the same with 404s. It is just a 404 header and message:

HTTP/1.1 404 Not Found
Date: Fri, 02 Sep 2005 08:19:54 GMT
Server: 5
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /fpi/testi.html was not found on this server.</p>
<p>Additionally, a 404 Not Found
error was encountered while trying to use an ErrorDocument to handle
the request.</p>
</body></html>

Maybe I was able to find something new regarding that. I have to explain
that the intention was to catch tomcats 404 error pages and instead
redirect the user or show him the general webserver error page. So I
created a 404 output rule (see it below, normally it should read
SecFilterSelective OUTPUT "HTTP Status 4[0-9][0-9]" but anyway).
I used evilstring as a placeholder in my last email. In fact, matching
evilstring works just fine. The real evil message which does not work is
that tomcat 404 page. That means: having the two output rules found
below and browsing the tomcat context, acess to a file containing
"evilstring" is being restricted fine with no internal server error. So
no problem there. But if you are tring to access a document inside the
context which is not there causing tomcat to send a 404 page to the
webserver, the 404 is being matched, but the custom error page is not
being delivered. So we have a pattern match and we can control the
headers (the header will be what is in mod_security.conf) but apache
gives back the internal server error as above (Just as if it could not
find the error page).

OK, so I created a file (testi.html) containing exactly the tomcat error
message. You can browse that file, modsecurity matches the 404 output
and you get the configured error page as expected. When I removed that
file and tried to access it again, tomcat was sending his 404 code and
the described error occured. You can see the requests in the L9 debug.

The only difference between the tomcat 404 and the webpage containing
exactly the same html code I can see is:

1. There is a trailing NULL at the end of the created webpage
2. The header sent by tomcat. When accessing the file, tomcat sends

HTTP/1.1 200 OK
ETag: W/"996-1125649082000"
Last-Modified: Fri, 02 Sep 2005 08:18:02 GMT
Content-Type: text/html
Content-Length: 996
Date: Fri, 02 Sep 2005 09:04:44 GMT
Server: Apache-Coyote/1.1
Connection: close

and after removing the file tomcat outputs

HTTP/1.1 404 /fpi/testi.html
Content-Type: text/html;charset=utf-8
Content-Length: 997
Date: Fri, 02 Sep 2005 09:05:55 GMT
Server: Apache-Coyote/1.1
Connection: close

Maybe it is about communication betwenn apache and mod_jk, where
modsecurity is not involved. But we can match that 404!?
Just have a look at the attached log. Maybe you have got an idea.
And here is my (stripped) config:

SecChrootDir /usr/local/jail
SecFilterEngine On
SecFilterScanPOST On
SecFilterCheckURLEncoding On
SecFilterCheckUnicodeEncoding Off
SecFilterCheckCookieFormat On
SecFilterNormalizeCookies On
SecFilterScanOutput On
SecFilterOutputMimeTypes "(null) text/html text/plain"
SecFilterForceByteRange 8 255
SecServerSignature "5"
SecAuditEngine RelevantOnly
SecAuditLog logs/audit_log
SecFilterDefaultAction "deny,log,pause:2231,status:404"
SecFilterDebugLog logs/modsec_debug_log
SecFilterDebugLevel 9
SecFilterSelective OUTPUT "evilstring"
SecFilterSelective OUTPUT "404"


Thanks in advance!
-mark


Ivan Ristic wrote:
> marks mlists wrote:
>
>> Hello modsec guys,
>>
>> I am sure someone already used modsecurity on a webserver which is
>> connecting to tomcat servers. I am running into the following problem:
>>
>> Having rules like SecFilterSelective OUTPUT "evilstring" is working fine
>> as long as the document containing that evilstring is being served by
>> apache itself or of course, via mod_proxy. But it does not work like I
>> want it to with mod_jk(2).
>>
>> If I request a page within a context mapped by mod_jk, p.e.
>> /app/evilfile containing the string, I get a successful pattern match:
>> mod_security: Access denied with code 200. Pattern match "evilstring"
>> at OUTPUT [uri "/app/evilfile"]
>
>
>   From the above log message it would appear mod_security is configured
>   to respond with status code 200.
>
>   What happens when you use:
>
>   SecFilterSelective OUTPUT evilstring log,deny,status:404
>
>   ?
>
>> So does someone of you have a clue what to do or where to have a look
>> at? Thanks in advance.
>
>
>   We need to look at your configuration files and, possibly,
>   your debug log entries at level 9. Look here for the instructions:
>   http://www.modsecurity.org/documentation/support-request-checklist.html
>


[/fpi/testi.html[2 sec_check_access_early: Early processing activated
[/fpi/testi.html[2 sec_check_access: Got called for request 187090
[/fpi/testi.html[9 Stored msr (187ed8) in r (187090)
[/fpi/testi.html[4 Normalised REQUEST_URI: "/fpi/testi.html"
[/fpi/testi.html[2 Parsing arguments...
[/fpi/testi.html[3 Content-Type is not available
[/fpi/testi.html[2 read_post_payload: Content-Length not available, chunked encoding not detected - assuming no request body
[/fpi/testi.html[4 Time #1: 0 usec
[/fpi/testi.html[4 Time #2: 0 usec
[/fpi/testi.html[2 sec_check_access: Got called for request 187090
[/fpi/testi.html[9 Found msr (187ed8) in r (187090)
[/fpi/testi.html[4 sec_check_access: Ignoring request that was already processed
[/fpi/testi.html[9 sec_insert_filter: Starting
[/fpi/testi.html[9 Found msr (187ed8) in r (187090)
[/fpi/testi.html[2 scan_pre: Adding output filter
[/fpi/testi.html[3 sec_filter_out: start
[/fpi/testi.html[9 Found msr (187ed8) in r (187090)
[/fpi/testi.html[3 sec_filter_out: Content-Type = "text/html"
[/fpi/testi.html[3 sec_filter_out: got Content-Length 996
[/fpi/testi.html[3 sec_filter_out: got 996 bytes, bufused=0, buflen=996
[/fpi/testi.html[3 sec_filter_out: start
[/fpi/testi.html[3 sec_filter_out: done reading
[/fpi/testi.html[2 Checking signature "404" at OUTPUT
[/fpi/testi.html[4 Checking against "<html><head><title>Apache Tomcat/5.0.28 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 404 - /fpi/teti.html</h1><HR size=\"1\" noshade=\"noshade\"><p><b>type</b> Status report</p><p><b>message</b> <u>/fpi/teti.html</u></p><p><b>description</b> <u>The requested resource (/fpi/teti.html) is not available.</u></p><HR size=\"1\" noshade=\"noshade\"><h3>Apache Tomcat/5.0.28</h3></body></html>\x0
[/fpi/testi.html[1 Access denied with code 404. Pattern match "404" at OUTPUT
[/fpi/testi.html[1 Pausing [/fpi/testi.html for 2231 ms
[/error.asis[2 sec_check_access_early: Early processing activated
[/error.asis[2 sec_check_access: Got called for request 18dc20
[/error.asis[9 Found msr (187ed8) in r->prev (187090)
[/error.asis[2 sec_check_access: Filtering off, not an initial request
[/error.asis[2 sec_check_access: Got called for request 18dc20
[/error.asis[9 Found msr (187ed8) in r->prev (187090)
[/error.asis[2 sec_check_access: Filtering off, not an initial request
[/error.asis[9 sec_insert_filter: Starting
[/error.asis[9 Found msr (187ed8) in r->prev (187090)
[/error.asis[2 sec_insert_filter: Skipping, output filtering already completed
[/error.asis[9 Found msr (187ed8) in r->prev (187090)
[/error.asis[2 sec_audit_logger_serial: start
[/error.asis[9 sec_audit_logger_serial: is_relevant=1, should_body_exist=0, is_body_read=0
[/fpi/testi.html[2 sec_check_access_early: Early processing activated
[/fpi/testi.html[2 sec_check_access: Got called for request 189098
[/fpi/testi.html[9 Stored msr (189ee0) in r (189098)
[/fpi/testi.html[4 Normalised REQUEST_URI: "/fpi/testi.html"
[/fpi/testi.html[2 Parsing arguments...
[/fpi/testi.html[3 Content-Type is not available
[/fpi/testi.html[2 read_post_payload: Content-Length not available, chunked encoding not detected - assuming no request body
[/fpi/testi.html[4 Time #1: 0 usec
[/fpi/testi.html[4 Time #2: 0 usec
[/fpi/testi.html[2 sec_check_access: Got called for request 189098
[/fpi/testi.html[9 Found msr (189ee0) in r (189098)
[/fpi/testi.html[4 sec_check_access: Ignoring request that was already processed
[/fpi/testi.html[9 sec_insert_filter: Starting
[/fpi/testi.html[9 Found msr (189ee0) in r (189098)
[/fpi/testi.html[2 scan_pre: Adding output filter
[/fpi/testi.html[3 sec_filter_out: start
[/fpi/testi.html[9 Found msr (189ee0) in r (189098)
[/fpi/testi.html[3 sec_filter_out: Content-Type = "text/html;charset=utf-8"
[/fpi/testi.html[3 sec_filter_out: got Content-Length 997
[/fpi/testi.html[3 sec_filter_out: got 997 bytes, bufused=0, buflen=997
[/fpi/testi.html[3 sec_filter_out: start
[/fpi/testi.html[3 sec_filter_out: done reading
[/fpi/testi.html[2 Checking signature "404" at OUTPUT
[/fpi/testi.html[4 Checking against "<html><head><title>Apache Tomcat/5.0.28 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 404 - /fpi/testi.html</h1><HR size=\"1\" noshade=\"noshade\"><p><b>type</b> Status report</p><p><b>message</b> <u>/fpi/testi.html</u></p><p><b>description</b> <u>The requested resource (/fpi/testi.html) is not available.</u></p><HR size=\"1\" noshade=\"noshade\"><h3>Apache Tomcat/5.0.28</h3></body></html>
[/fpi/testi.html[1 Access denied with code 404. Pattern match "404" at OUTPUT
[/fpi/testi.html[1 Pausing [/fpi/testi.html for 2231 ms
[/fpi/testi.html[9 Found msr (189ee0) in r (189098)
[/fpi/testi.html[2 sec_audit_logger_serial: start
[/fpi/testi.html[9 sec_audit_logger_serial: is_relevant=1, should_body_exist=0, is_body_read=0


SunOS xx 5.9 Generic_118558-06 sun4u sparc SUNW,Sun-Fire-V210

Server version: Apache/2.0.54
Server built:   May 24 2005 17:07:25
Server's Module Magic Number: 20020903:9
Architecture:   32-bit
Server compiled with....
-D APACHE_MPM_DIR="server/mpm/prefork"
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_FCNTL_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D HTTPD_ROOT="/usr/local/apache2"
-D SUEXEC_BIN="/usr/local/apache2/bin/suexec"
-D DEFAULT_PIDLOG="logs/httpd.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_LOCKFILE="logs/accept.lock"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="conf/mime.types"
-D SERVER_CONFIG_FILE="conf/httpd.conf"

Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c