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


11

我将以下内容放入应用程序的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>

好的,所以现在:

如果我使用的方法发出请求,DELETE则会返回403。

如果我使用的方法发出请求,delete则会返回403。

如果我用的方法提出要求,DeLeTe我会确定的!

如何使它们不区分大小写?

编辑:我正在使用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;
        }
    }

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());
%>

你如何测试呢?
哈维尔·卢卡斯

@XavierLucas,将其添加到问题中
developerwjk

1
您的测试程序有缺陷。HttpWebRequest不区分大小写地 识别标准HTTP方法并将其转换为大写。此外,它被记录为仅允许标准HTTP方法。最好的选择是使用原始TCP流(例如,在netcat,PuTTY raw或telnet等中)。
鲍勃

1
@Bob,我是在Visual C#2005 Express的.NET 2.0中完成的,没有遇到任何这些问题。它发送的正是我输入的内容。因此,他们必须在更高版本中进行更改。
developerwjk

1
@鲍勃,哈哈。Microsoft的文档是错误的/具有误导性。对于.NET 2.0版本,他们还说:“ Method属性可以设置为任何HTTP 1.1协议动词:GET,HEAD,POST,PUT,DELETE,TRACE或OPTIONS。” 但这在实践中并不受任何限制。
developerwjk

Answers:


13

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

例如,以下白名单将阻止除区分大小写 GET和之外的所有方法HEAD

<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>

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

参考


当我使用POST进行此操作时,我转到网站上的页面(只需单击链接或书签即可),它给了我405。–
developerwjk

实际上,它给了我HTTP状态403-对请求资源的访问已被拒绝
developerwjk

我已经在服务器的web.xml中进行了尝试,它忽略了所有遗漏,只是阻止了所有内容。拿出来。在应用程序的web.xml中对其进行了尝试,并且再次,它只是阻塞了每种方法并忽略了遗漏。
developerwjk

也完全按照上面的方法尝试,但是取出<auth-constraint />后就可以容纳所有内容。
developerwjk

2
@developerwjk http-method-omission最初是在Servlet API 3.0中定义的,该API由Tomcat 7+实现:tomcat.apache.org/whichversion.html。不幸的是,这意味着这在Tomcat 6及更低版本的Tomcat 6中将不起作用(注意:5已经停止销售)。您可以尝试在链接的SO问题中尝试另一种建议的解决方案,该问题建议设置两个单独的security-constraints-我无法确认其中一个在7中有效,因此未在此答案中包括它。
鲍勃

13

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

例如 :

$ { 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

我必须说,我在这里感到有些震惊,看到这种行为扩展到所有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

3
注意:RFC 2616现在已由RFC 7230-7235取代。RFC 7230§3.1.1:“请求方法区分大小写。” RFC 7231§4:“按照惯例,标准化方法以全大写的US-ASCII字母定义。”,然后在答案中列出相同的列表。
鲍勃

1
响应状态代码实际上应为405方法不允许。
Lie Ryan

3
@LieRyan否,因为这意味着方法令牌适合RFC,而服务器不允许在资源上使用它。RFC 2616§10.4.1:[400错误的请求] 由于语法格式错误,服务器无法理解该请求。RFC 2616§10.4.6 [405不允许方法 ] 对于由Request-URI标识的资源,不允许在请求行中指定方法令牌无论如何get都不是HTTP 方法(请参见RFC 2616§5.1.1的摘录)
Xavier Lucas

@XavierLucas:使用小写方法不是语法错误,请检查RFC2616第5节。在ABNF中,extension-method语法应token包括所有字母数字字符和一些符号,而不仅仅是RFC中明确列出的方法。只要客户端和服务器都同意如何扩展它们,HTTP的几乎每个部分都是可扩展的,包括定义自己的小写方法。请求行“ get / HTTP / 1.1”在语法上很好,它只是违反了RFC,因此该方法名称应区分大小写。
Lie Ryan

@LieRyan这里extension-method是打开下一个RFC的大门,不是在RFC范围之外添加您自己的方法,并假装您正在运行与HTTP / 1.1兼容的服务。因此,应该返回400,因为在最新的RFC中还没有出现这样的方法,所以今天这是无效的令牌。如果令牌对于当前方法列表有效,并且在服务器端实现,但不允许,则应返回405。万一该方法有效但未在服务器端实现,则应返回501。
哈维尔·卢卡斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.