Wenn Sie HTTP-Methoden unter Tomcat nicht zulassen, wird zwischen Groß- und Kleinschreibung unterschieden?

11

Ich habe Folgendes in die web.xml meiner Anwendung eingefügt, um zu versuchen, PUT, DELETE usw. Nicht zuzulassen:

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

Ok, also jetzt:

Wenn ich eine Anfrage mit der Methode von mache, DELETEbekomme ich eine 403 zurück.

Wenn ich eine Anfrage mit der Methode von mache, deletebekomme ich eine 403 zurück.

ABER

Wenn ich eine Anfrage mit der Methode von mache, DeLeTebekomme ich OK!

Wie kann ich dafür sorgen, dass diese Groß- und Kleinschreibung nicht berücksichtigt wird?

Bearbeiten: Ich teste es mit einem C # -Programm:

    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.Textist ein Textfeld, in das ich den Methodennamen eingebe. Wenn es eine 403 gibt, wird eine Ausnahme ausgelöst, die im catch-Block abgefangen wird.

Die Datei cache_test.jsp enthält:

<%
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());
%>
developerwjk
quelle
Wie testest du es?
Xavier Lucas
@ XavierLucas, fügte hinzu, dass zu der Frage
Entwicklerwjk
1
Ihr Testprogramm ist fehlerhaft. HttpWebRequestwird case-insensitiv erkennen und konvertieren Standard - HTTP - Methoden in Großbuchstaben. Darüber hinaus wird dokumentiert, dass nur Standard-HTTP-Methoden zulässig sind. Die beste Option ist die Verwendung eines unformatierten TCP-Streams (z. B. in Netcat, PuTTY Raw oder Telnet usw.).
Bob
1
@ Bob, ich habe es in .NET 2.0 in Visual C # 2005 Express gemacht und bin auf keines dieser Probleme gestoßen. Es sendet genau das, was ich tippe. Das müssen sie also in einer späteren Version geändert haben.
Entwicklerwjk
1
@ Bob, Lol. Die Dokumentation von Microsoft ist falsch / irreführend. Für die .NET 2.0-Version heißt es außerdem: "Die Method-Eigenschaft kann auf eines der HTTP 1.1-Protokollverben festgelegt werden: GET, HEAD, POST, PUT, DELETE, TRACE oder OPTIONS." In der Praxis beschränkt sich dies jedoch in keiner Weise darauf.
Entwicklerwjk

Antworten:

13

Unabhängig von Tomcats falschem Verhalten in Bezug auf den HTTP-Standard sollten Sie eine Whitelist verwenden, um bestimmte Methoden anstelle einer Blacklist zuzulassen.

Die folgende Whitelist blockiert beispielsweise alle Methoden mit Ausnahme der Groß- und Kleinschreibung GET und 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>

(Hinweis: erfordert Tomcat 7+. Wer ältere Versionen verwendet, muss andere Lösungen untersuchen, z. B. einen Servlet-Filter.)

Ref

Bob
quelle
Wenn ich das mit POST mache, gehe ich zu einer Seite auf der Site (klicke einfach auf einen Link oder ein Lesezeichen) und es gibt mir eine 405.
developerwjk
Eigentlich gibt es mir HTTP-Status 403 - Der Zugriff auf die angeforderte Ressource wurde verweigert
developerwjk
Ich habe es in der web.xml des Servers versucht, und es hat die Auslassungen ignoriert und einfach alles blockiert. Hat das rausgenommen. Versuchte es in der web.xml der Anwendung und wieder blockiert es einfach jede Methode und ignoriert die Auslassungen.
Entwicklerwjk
Auch genau wie oben versucht, aber herausnehmen <auth-constraint />und dann erlaubt es einfach alles.
Entwicklerwjk
2
@developerwjk http-method-omissionwurde erstmals in der Servlet-API 3.0 definiert, die von Tomcat 7+ implementiert wird: tomcat.apache.org/whichversion.html . Leider bedeutet dies, dass dies in Tomcat 6 und älter nicht funktioniert (Hinweis: 5 ist bereits EOL). Sie können die andere vorgeschlagene Lösung in der verknüpften SO-Frage ausprobieren, in der empfohlen wird, zwei separate security-constraints festzulegen. Ich konnte nicht bestätigen, dass eines in 7 funktioniert, habe es also nicht in diese Antwort aufgenommen.
Bob
13

Nun, nach einem kurzen Test über einige zufällige Server, Server: Apache-Coyottederen HTTP-Antworten get / HTTP/1.1\r\nHost: <target_IP>\r\n\r\neine Headersignatur enthalten , scheint es richtig zu sein, dass das Senden mit einer einfachen Netcat-Verbindung jedes Mal funktioniert, wenn ein 400-HTTP-Code hätte empfangen werden sollen.

Zum Beispiel :

$ { 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.@[email protected].......
..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

Ich muss sagen, dass ich hier ein bisschen schockiert bin und ich wäre nicht überrascht zu sehen, dass sich dieses Verhalten in diesem Fall auf alle HTTP / 1.1-Methoden erstreckt.

Sie sollten einen Fehlerbericht über das Fehlerverfolgungstool ausfüllen und eine E-Mail an die entsprechende Mailingliste senden, da dies eine hässliche Verletzung von RFC 2616 (siehe unten) mit schwerwiegenden Folgen ist.

5.1.1 Methode

  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
Xavier Lucas
quelle
3
Hinweis: RFC 2616 wird jetzt durch RFC 7230-7235 ersetzt. RFC 7230 § 3.1.1 : "Bei der Anforderungsmethode wird zwischen Groß- und Kleinschreibung unterschieden." RFC 7231 § 4 : "Standardmäßig werden standardisierte Methoden in US-ASCII-Großbuchstaben definiert.", Gefolgt von derselben Liste in Ihrer Antwort.
Bob
1
Der Antwortstatuscode sollte tatsächlich 405 Methode nicht zulässig sein.
Lie Ryan
3
@LieRyan Nein, da dies bedeuten würde, dass das Methoden-Token zum RFC passt, während der Server nicht zulässt, dass es für diese Ressource verwendet wird. RFC 2616 § 10.4.1: [400 Bad Request] Die Anfrage konnte vom Server aufgrund einer fehlerhaften Syntax nicht verstanden werden. RFC 2616 § 10.4.6 [405 Methode nicht zulässig] Die in der Anforderungszeile angegebene Methode ist für die durch die Anforderungs-URI angegebene Ressource nicht zulässig. Das Token getist in keiner Weise eine HTTP- Methode (siehe den Auszug aus RFC 2616 § 5.1.1 oben)
Xavier Lucas
@XavierLucas: Die Verwendung der Kleinbuchstabenmethode ist kein Syntaxfehler. Überprüfen Sie den RFC2616-Abschnitt 5 . Haben Sie in der ABNF extension-methodeine Syntax, tokendie alle alphanumerischen Zeichen und einige Symbole enthält, nicht nur die im RFC speziell aufgeführten Methoden. Fast jeder Teil von HTTP ist erweiterbar, sofern sowohl Client als auch Server übereinstimmen, wie sie zu erweitert werden, einschließlich der Definition Ihrer eigenen Kleinbuchstabenmethoden. Die Anforderungszeile "get / HTTP / 1.1" ist syntaktisch in Ordnung. Sie verstößt nur gegen den RFC, da der Methodenname zwischen Groß- und Kleinschreibung unterscheiden sollte.
Lie Ryan
@LieRyan Das extension-methodist hier, um die Tür für die nächsten RFCs offen zu lassen. Dies ist nicht hier, um Ihre eigenen Methoden aus dem RFC-Bereich hinzuzufügen und so zu tun, als würden Sie HTTP / 1.1-kompatible Dienste ausführen. Daher sollte eine 400 zurückgegeben werden, da in der neuesten RFC noch keine solche Methode aufgetaucht ist. Dies ist heute ein ungültiges Token. Wenn das Token in Bezug auf die aktuelle Methodenliste gültig und serverseitig implementiert, aber nicht zulässig war, sollte ein 405 zurückgegeben werden. Ein 501 sollte zurückgegeben werden, falls die Methode gültig, aber nicht serverseitig implementiert ist.
Xavier Lucas