Tomcat에서 HTTP 메소드를 허용하지 않는 것은 대소 문자를 구분합니까?


11

PUT, DELETE 등을 허용하지 않으려 고 응용 프로그램의 web.xml에 다음을 입력했습니다.

 <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하면 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;
        }
    }

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

어떻게 테스트합니까?
Xavier Lucas

@XavierLucas, 질문에 추가
developerwjk

1
테스트 프로그램에 결함이 있습니다. HttpWebRequest대문자와 소문자를 구별하지 않고로 인식하고 변환 대문자로 표준 HTTP 방법을. 또한 표준 HTTP 메소드 만 허용 하는 것으로 문서화 되어 있습니다. 가장 좋은 옵션은 원시 TCP 스트림 (예 : netcat, PuTTY raw 또는 telnet 등)을 사용하는 것입니다.
Bob

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

답변:


13

HTTP 표준과 관련하여 Tomcat의 잘못된 동작에 관계없이 블랙리스트가 아닌 특정 방법을 허용하려면 화이트리스트를 사용해야합니다.

예를 들어, 다음 방법을 제외한 모든 차단 허용 목록 대소 문자 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>

(참고 : Tomcat 7 이상이 필요합니다. 이전 버전을 사용하는 사용자는 서블릿 필터와 같은 다른 솔루션을 조사해야합니다.)

심판


POST가 포함 된 상태에서이를 수행하면 사이트의 페이지 (링크 나 책갈피를 클릭하기 만하면)로 이동하여 405를 제공합니다.
developerwjk

실제로 그것은 나를 HTTP 상태 403 제공합니다-요청 된 자원에 대한 액세스가 거부되었습니다
developerwjk

서버의 web.xml에서 시도했지만 누락을 무시하고 모든 것을 차단했습니다. 그거 알아 냈어 응용 프로그램의 web.xml에서 시도했지만 모든 메소드를 차단하고 누락을 무시했습니다.
developerwjk

또한 위와 같이 정확하게 시도했지만 꺼내고 <auth-constraint />모든 것을 허용합니다.
developerwjk

2
@developerwjk은 http-method-omission제 7 이상 톰캣 구현 서블릿 API 3.0에서 정의되었다 tomcat.apache.org/whichversion.html를 . 불행히도 이것은 Tomcat 6 이상에서는 작동하지 않습니다 (참고 : 5는 이미 EOL 임). 링크 된 SO 질문 에서 다른 제안 된 솔루션을 시도하여 두 개의 개별 security-constraints를 설정하는 것이 좋습니다. 하나가 7에서 작동하는지 확인할 수 없으므로이 답변에 포함시키지 않았습니다.
Bob

13

글쎄, Server: Apache-CoyotteHTTP 응답에 헤더 서명이있는 임의의 임의 서버를 빠르게 테스트 한 후에 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 문자로 정의됩니다."다음에 답에서 동일한 목록이 표시됩니다.
Bob

1
응답 상태 코드는 실제로 405 Method Not Allowed 여야합니다.
Lie Ryan

3
@LieRyan 아니요. 서버가이 리소스에서 사용할 수는 없지만 메서드 토큰은 RFC에 맞습니다. RFC 2616 § 10.4.1 : [400 잘못된 요청] 잘못된 구문으로 인해 서버에서 요청을 이해할 수 없습니다. RFC 2616 § 10.4.6 [405 방법은 허용되지] 방법 요청 라인에 지정된는 요청-URI로 식별 된 자원에 사용할 수 없습니다. 토큰 은 어떤 방식 으로든 HTTP 메소드 가 아닙니다 (위 RFC 2616 § 5.1.1 발췌 참조)get
Xavier Lucas

@ XavierLucas : 소문자 방법을 사용하는 것이 구문 오류가 아닌 경우 RFC2616 섹션 5를 확인하십시오 . ABNF 에는 RFC에 구체적으로 나열된 방법뿐만 아니라 모든 영숫자 문자와 일부 기호를 포함하는 extension-method구문 token이 있습니다. 클라이언트와 서버 모두 자신의 소문자 메소드 정의를 포함하여 너무 확장되는 방식에 동의하는 한 HTTP의 거의 모든 부분을 확장 할 수 있습니다. 요청 라인 "get / HTTP / 1.1"은 구문 상 문제가 없으며, 메소드 이름은 대소 문자를 구분해야하는 RFC를 위반합니다.
Lie Ryan

@LieRyan extension-method다음 RFC에 대한 문을 열어두기 위해 여기에 있습니다. RFC의 범위에서 사용자 고유의 메소드를 추가하고 HTTP / 1.1 호환 서비스를 실행하고있는 것처럼 보이지는 않습니다. 따라서 최신 RFC에 아직 그러한 방법이 나타나지 않았기 때문에 400이 반환되어야하므로 오늘날 유효하지 않은 토큰입니다. 현재 메소드 목록과 관련하여 토큰이 유효하고 서버 측에서 구현되었지만 허용되지 않은 경우 405가 리턴되어야합니다. 메소드가 유효하지만 서버 측에서 구현되지 않은 경우 501을 리턴해야합니다.
Xavier Lucas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.