Disallowing HTTP methods on Tomcat is case sensitive?

Solution 1:

Well, after quick testing over some random servers holding Server: Apache-Coyotte header signature in their HTTP replies, it seems you are right as sending get / HTTP/1.1\r\nHost: <target_IP>\r\n\r\n with a simple netcat connection worked every time while a 400 HTTP code should have been received.

For instance :

$ { echo -en "get / HTTP/1.1\r\nHost: <target_IP>:8080\r\n\r\n" ; } | nc <target_IP> 8080

01:14:58.095547 IP > <target_IP>.8080: Flags [P.], seq 1:42, ack 1, win 115, options [nop,nop,TS val 4294788321 ecr 0], length 41
E..]C.@[email protected].......
..D.....get / HTTP/1.1
Host: <target_IP>:8080


01:14:58.447946 IP <target_IP>.8080 > Flags [.], seq 1:1409, ack 43, win 65494, options [nop,nop,TS val 7981294 ecr 4294787971], length 1408
.y....C.HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Transfer-Encoding: chunked
Date: Tue, 27 Jan 2015 00:15:14 GMT

I must say I'm a bit shocked here and I would not be surprised to see that behaviour extended to all HTTP/1.1 methods in such case.

You should fill a bug report on their bug tracking tool and send a mail to the appropriate mailing list because that's one ugly violation of RFC 2616 (see below) with bad consequences.

5.1.1 Method

  The Method  token indicates the method to be performed on the
  resource identified by the Request-URI. The method is case-sensitive.

      Method         = "OPTIONS"                ; Section 9.2
                     | "GET"                    ; Section 9.3
                     | "HEAD"                   ; Section 9.4
                     | "POST"                   ; Section 9.5
                     | "PUT"                    ; Section 9.6
                     | "DELETE"                 ; Section 9.7
                     | "TRACE"                  ; Section 9.8
                     | "CONNECT"                ; Section 9.9
                     | extension-method
      extension-method = token

Solution 2:

Regardless of Tomcat's incorrect behaviour with regards to the HTTP standard, you should be using a whitelist to allow specific methods rather than a blacklist.

For example, the following whitelist will block all methods except the case-sensitive GET and HEAD.

        <web-resource-name>restricted methods</web-resource-name>
    <auth-constraint />

(Note: requires Tomcat 7+. Those using older versions will have to investigate other solutions, e.g. a servlet filter.)