在 Tomcat 上禁止 HTTP 方法是否区分大小写?

dev*_*wjk 12 tomcat

我已将以下内容放在我的应用程序的 web.xml 中以尝试禁止 PUT、DELETE 等:

 <security-constraint>
 <web-resource-collection>
  <web-resource-name>restricted methods</web-resource-name>
  <url-pattern>/*</url-pattern>
  <http-method>DELETE</http-method>
  <http-method>PUT</http-method>
  <http-method>SEARCH</http-method>
  <http-method>COPY</http-method>
  <http-method>MOVE</http-method>
  <http-method>PROPFIND</http-method>
  <http-method>PROPPATCH</http-method>
  <http-method>MKCOL</http-method>
  <http-method>LOCK</http-method>
  <http-method>UNLOCK</http-method>
  <http-method>delete</http-method>
  <http-method>put</http-method>
  <http-method>search</http-method>
  <http-method>copy</http-method>
  <http-method>move</http-method>
  <http-method>propfind</http-method>
  <http-method>proppatch</http-method>
  <http-method>mkcol</http-method>
  <http-method>lock</http-method>
  <http-method>unlock</http-method>
 </web-resource-collection>
 <auth-constraint />
 </security-constraint>
Run Code Online (Sandbox Code Playgroud)

好的,现在:

如果我使用方法提出请求,DELETE我会得到 403 返回。

如果我使用方法提出请求,delete我会得到 403 返回。

如果我用DeLeTe我的方法做一个请求就OK了!

我怎样才能让它禁止这些不区分大小写的?

编辑:我正在用 C# 程序测试它:

    private void button1_Click(object sender, EventArgs e)
    {
        textBox1.Text = "making request";
        System.Threading.Thread.Sleep(400);
        WebRequest req = WebRequest.Create("http://serverurl/Application/cache_test.jsp");
        req.Method = txtMethod.Text;
        try
        {
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

            textBox1.Text = "Status: " + resp.StatusCode;

            if (resp.StatusCode == System.Net.HttpStatusCode.OK)
            {
                WebHeaderCollection header = resp.Headers;
                using (System.IO.StreamReader reader = new System.IO.StreamReader(resp.GetResponseStream(), ASCIIEncoding.ASCII))
                {
                    //string responseText = reader.ReadToEnd();
                    textBox1.Text += "\r\n" + reader.ReadToEnd();
                }
            }
        }
        catch (Exception ex)
        {
            textBox1.Text = ex.Message;
        }
    }
Run Code Online (Sandbox Code Playgroud)

txtMethod.Text是一个文本框,我在其中输入方法名称。当出现 403 时,会抛出异常,并在 catch 块中捕获该异常。

cache_test.jsp 包含:

<%
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma","no-cache");

out.print("Method used was: "+request.getMethod());
%>
Run Code Online (Sandbox Code Playgroud)

Bob*_*Bob 14

不管 Tomcat 在 HTTP 标准方面的错误行为如何,您都应该使用白名单来允许特定方法而不是黑名单。

例如,以下白名单将阻止除区分大小写 GETHEAD.

<security-constraint>
    <web-resource-collection>
        <web-resource-name>restricted methods</web-resource-name>
        <url-pattern>/*</url-pattern>
        <http-method-omission>GET</http-method-omission>
        <http-method-omission>HEAD</http-method-omission>
    </web-resource-collection>
    <auth-constraint />
</security-constraint>
Run Code Online (Sandbox Code Playgroud)

(注意:需要 Tomcat 7+。使用旧版本的用户必须研究其他解决方案,例如 servlet 过滤器。)

参考

  • @developerwjk `http-method-omission` 最初定义在 Servlet API 3.0 中,由 Tomcat 7+ 实现:http://tomcat.apache.org/whichversion.html。不幸的是,这意味着这在 Tomcat 6 及更早版本中不起作用(注意:5 已经是 EOL)。您可以在 [linked SO question](http://stackoverflow.com/questions/8069640/whitelist-security-constraint-in-web-xml) 中尝试其他建议的解决方案,该解决方案建议设置两个单独的`security-constraint`s - 我无法确认一个在 7 中有效,所以没有将它包含在这个答案中。 (2认同)

Xav*_*cas 13

好吧,在对一些Server: Apache-Coyotte在其 HTTP 回复中包含标头签名的随机服务器进行快速测试后,似乎您是正确的,因为get / HTTP/1.1\r\nHost: <target_IP>\r\n\r\n每次使用简单的 netcat 连接发送都可以工作,而应该收到 400 HTTP 代码。

例如 :

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

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

[...]

01:14:58.447946 IP <target_IP>.8080 > 192.168.1.3.57245: Flags [.], seq 1:1409, ack 43, win 65494, options [nop,nop,TS val 7981294 ecr 4294787971], length 1408
E...f...i.....p.............A..............
.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
Run Code Online (Sandbox Code Playgroud)

我必须说我在这里有点震惊,在这种情况下看到这种行为扩展到所有 HTTP/1.1 方法我不会感到惊讶。

您应该在他们的错误跟踪工具上填写错误报告并将邮件发送到适当的邮件列表,因为这是对 RFC 2616(见下文)的一个丑陋的违反,会产生不良后果。

5.1.1 方法

  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
Run Code Online (Sandbox Code Playgroud)

  • 注意:RFC 2616 现在被 RFC 7230-7235 取代。[RFC 7230 § 3.1.1](http://tools.ietf.org/html/rfc7230#section-3.1.1):“请求方法区分大小写。” [RFC 7231 § 4](http://tools.ietf.org/html/rfc7231#section-4):“按照惯例,标准化方法以全大写的 US-ASCII 字母定义。”,后跟相同的列表在你的回答中。 (3认同)
  • @LieRyan 否,因为这意味着方法令牌符合 RFC,而服务器不允许在此资源上使用它。RFC 2616 § 10.4.1 : [400 Bad Request] *由于语法格式错误,服务器无法理解该请求。* RFC 2616 § 10.4.6 [405 Method Not Allowed] *在Request-Line 不允许用于由 Request-URI 标识的资源。* 令牌 `get` 无论如何都不是 HTTP **方法**(参见上面 RFC 2616 § 5.1.1 的摘录) (3认同)