When an "options" http request is made to Tomcat to a directory that has no default file (like index.jsp) in it, Tomcat reports a full list of allowed verbs, when in fact, most of them are NOT allowed. For example, a request to a generic img directory: OPTIONS /img/ HTTP/1.0 Cookie: JSESSIONID=C46C2E18BE95AD91828C9370CBDF0AF2 Content-Length: 0 Accept: */* Accept-Language: en-us Connection: Keep-Alive User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1 4322; InfoPath.1) Returns: HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS Content-Length: 0 Date: Mon, 24 Apr 2006 15:11:16 GMT Connection: close Which shows several destructive options available (PUT, DELETE). But a request to DELETE or PUT (correctly) returns a 403 FORBIDDEN result: DELETE /img/ HTTP/1.0 Cookie: JSESSIONID=C46C2E18BE95AD91828C9370CBDF0AF2 Content-Length: 0 Accept: */* Accept-Language: en-us Connection: Keep-Alive User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1 4322; InfoPath.1) Returns: HTTP/1.1 403 Forbidden Server: Apache-Coyote/1.1 Content-Type: text/html;charset=utf-8 Content-Length: 964 Date: Mon, 24 Apr 2006 15:12:31 GMT Connection: close Because the initial OPTIONS request returns a list containing dangerous verbs, the directory will be flagged as a serious security vulnerability by most scanners (a false positive). The issue DOES NOT occur when the directory HAS a default file in it: OPTIONS /user_management/ HTTP/1.0 Cookie: JSESSIONID=C46C2E18BE95AD91828C9370CBDF0AF2 Content-Length: 0 Accept: */* Accept-Language: en-us Connection: Keep-Alive User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1 4322; InfoPath.1) Returns: HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Set-Cookie: JSESSIONID=BC992F0C86E2BCBD0A2E5F1B3A12C50C; Path=/ Content-Type: text/html;charset=ISO-8859-1 Date: Mon, 24 Apr 2006 15:14:27 GMT Connection: close
Confirming the bug on Tomcat 5.5.17 where Coyote reports itself as Apache-Coyote/1.1. Steps to reproduce: $ telnet example.com 8080 OPTIONS /directory/ HTTP/1.0 HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Allow: GET, HEAD, POST, TRACE, OPTIONS Content-Type: text/html Content-Length: 0 Date: Thu, 20 Mar 2008 00:44:46 GMT Connection: close What's interesting, the same request using HTTP/1.1 instead of HTTP/1.0 fails: $ telnet example.com 8080 OPTIONS /directory/ HTTP/1.1 HTTP/1.1 400 Bad Request Server: Apache-Coyote/1.1 Transfer-Encoding: chunked Date: Thu, 20 Mar 2008 00:51:03 GMT Connection: close 0
(In reply to comment #1) > Confirming the bug on Tomcat 5.5.17 where Coyote reports itself as > Apache-Coyote/1.1. > > Steps to reproduce: > > $ telnet example.com 8080 > OPTIONS /directory/ HTTP/1.0 > > HTTP/1.1 200 OK > Server: Apache-Coyote/1.1 > Allow: GET, HEAD, POST, TRACE, OPTIONS > Content-Type: text/html > Content-Length: 0 > Date: Thu, 20 Mar 2008 00:44:46 GMT > Connection: close > > > What's interesting, the same request using HTTP/1.1 instead of HTTP/1.0 fails: > > $ telnet example.com 8080 > OPTIONS /directory/ HTTP/1.1 > > HTTP/1.1 400 Bad Request > Server: Apache-Coyote/1.1 > Transfer-Encoding: chunked > Date: Thu, 20 Mar 2008 00:51:03 GMT > Connection: close > > 0 > IF you want HTTP/1.1 shouldn't you create a valid HTTP/1.1 request?
The Allow header should contain those methods for which the server would not return 405 (Not Allowed). Thus, if it returns 403 for DELETE, it's totally correct to include DELETE in the Allow header. In doubt, come over to the HTTP mailing list for further discussion :-).
Julian Reschke wrote: >The Allow header should contain those methods for which the server would not >return 405 (Not Allowed). > >Thus, if it returns 403 for DELETE, it's totally correct to include DELETE in >the Allow header. Actually it returns 405 for TRACE method: $ telnet example.com 8080 OPTIONS /directory/ HTTP/1.0 HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Allow: GET, HEAD, POST, TRACE, OPTIONS Content-Type: text/html Content-Length: 0 Date: Thu, 20 Mar 2008 17:19:57 GMT Connection: close $ telnet example.com 8080 TRACE /directory/ HTTP/1.0 X-Test-Header: blahblah HTTP/1.1 405 TRACE method is not allowed Server: Apache-Coyote/1.1 Allow: OPTIONS Content-Length: 0 Date: Thu, 20 Mar 2008 17:20:18 GMT Connection: close _This_ behaviour is inconsistent IMO. Correct me if I'm wrong. ======= Filip Hanik wrote > IF you want HTTP/1.1 shouldn't you create a valid HTTP/1.1 request? What do you mean? I don't see any deviations from RFC 2616 in my second HTTP/1.1 request (although the RFC is quite unspecific on OPTIONS method).
Filip's point is that you get a 400 since you have no host header in your request. I have modified the default servlet to include TRACE in the Allow header based on the setting of allowTrace for the connector associated with the request. This change has been made to trunk and proposed for 6.0.x and 5.5.x.
This has been fixed in 6.0.x and will be included in 6.0.19 onwards.
This was fixed a few months ago in 5.5.x and will be included in 5.5.28 onwards