Menolak metode HTTP pada Tomcat peka huruf besar-kecil?

11

Saya telah memasukkan yang berikut ini di web.xml aplikasi saya untuk mencoba melarang PUT, DELETE, dll .:

 <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 jadi sekarang:

Jika saya melakukan permintaan dengan metode DELETEsaya mendapatkan kembali 403.

Jika saya melakukan permintaan dengan metode deletesaya mendapatkan kembali 403.

TAPI

Jika saya melakukan permintaan dengan metode DeLeTesaya mendapatkan OK!

Bagaimana saya bisa membuatnya tidak peka terhadap huruf besar-kecil ini?

Sunting: Saya mengujinya dengan program 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.Textadalah kotak teks tempat saya mengetik nama metode. Ketika ada 403 pengecualian dilemparkan yang ditangkap di blok tangkap.

Cache_test.jsp berisi:

<%
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
sumber
Bagaimana Anda mengujinya?
Xavier Lucas
@XavierLucas, Menambahkan itu ke pertanyaan
developerwjk
1
Program pengujian Anda cacat. HttpWebRequestakan mengenali dan mengubah metode HTTP standar menjadi huruf besar secara tidak sensitif . Selain itu, ini didokumentasikan sebagai hanya memungkinkan metode HTTP standar. Pilihan terbaik adalah menggunakan aliran TCP mentah (mis. Dalam netcat, atau PuTTY raw, atau telnet, dll.).
Bob
1
@ Bob, saya melakukannya di. NET 2.0 di Visual C # 2005 Express dan tidak mengalami masalah tersebut. Itu mengirim persis apa yang saya ketik. Jadi mereka harus mengubahnya dalam versi yang lebih baru.
developerwjk
1
@ Bob, Lol. Dokumentasi Microsoft salah / menyesatkan. Untuk versi .NET 2.0 mereka juga mengatakan "Properti Metode dapat diatur ke salah satu kata kerja protokol HTTP 1.1: GET, HEAD, POST, PUT, DELETE, TRACE, atau OPTIONS." Tapi itu tidak terbatas pada cara apa pun dalam praktiknya.
developerwjk

Jawaban:

13

Terlepas dari perilaku Tomcat yang salah terkait dengan standar HTTP, Anda harus menggunakan daftar putih untuk mengizinkan metode tertentu daripada daftar hitam.

Sebagai contoh, daftar putih berikut akan memblokir semua metode kecuali case-sensitive GET dan 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>

(Catatan: memerlukan Tomcat 7+. Mereka yang menggunakan versi yang lebih lama harus menyelidiki solusi lain, misalnya filter servlet.)

Ref

Bob
sumber
Ketika saya melakukannya dengan POST juga termasuk, saya pergi ke halaman di situs (hanya mengklik tautan atau bookmark ke sana) dan itu memberi saya 405.
developerwjk
Sebenarnya itu memberi saya Status HTTP 403 - Akses ke sumber daya yang diminta telah ditolak
developerwjk
Saya sudah mencobanya di web.xml server, dan mengabaikan kelalaian dan hanya memblokir semuanya. Mengambil itu. Mencoba di web.xml aplikasi, dan sekali lagi, itu hanya memblokir setiap metode dan mengabaikan kelalaian.
developerwjk
Juga mencoba persis seperti di atas tetapi mengambil <auth-constraint />dan kemudian hanya memungkinkan semuanya.
developerwjk
2
@developerwjk http-method-omissionpertama kali didefinisikan di dalam Servlet API 3.0, yang diimplementasikan oleh Tomcat 7+: tomcat.apache.org/whichversion.html . Sayangnya, ini berarti ini tidak akan berfungsi di Tomcat 6 dan lebih lama (catatan: 5 sudah EOL). Anda dapat mencoba solusi lain yang diusulkan dalam pertanyaan SO tertaut yang merekomendasikan pengaturan dua security-constraints terpisah - saya tidak dapat mengkonfirmasi bahwa satu berfungsi dalam 7, jadi tidak termasuk dalam jawaban ini.
Bob
13

Nah, setelah pengujian cepat atas beberapa server acak yang memegang Server: Apache-Coyottetandatangan header di balasan HTTP mereka, tampaknya Anda benar karena mengirim get / HTTP/1.1\r\nHost: <target_IP>\r\n\r\ndengan koneksi netcat sederhana berfungsi setiap kali sementara 400 kode HTTP seharusnya diterima.

Contohnya :

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

Saya harus mengatakan saya sedikit terkejut di sini dan saya tidak akan terkejut melihat bahwa perilaku diperluas ke semua metode HTTP / 1.1 dalam kasus seperti itu.

Anda harus mengisi laporan bug pada alat pelacak bug mereka dan mengirim email ke mailing list yang sesuai karena itu adalah satu pelanggaran jelek terhadap RFC 2616 (lihat di bawah) dengan konsekuensi buruk.

5.1.1 Metode

  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
sumber
3
Catatan: RFC 2616 sekarang diganti oleh RFC 7230-7235. RFC 7230 § 3.1.1 : "Metode permintaan peka huruf besar-kecil." RFC 7231 § 4 : "Secara konvensi, metode standar didefinisikan dalam huruf AS-ASCII semua-huruf besar.", Diikuti oleh daftar yang sama dalam jawaban Anda.
Bob
1
Kode status respons sebenarnya harus 405 Metode Tidak Diizinkan.
Lie Ryan
3
@ LieRyan Tidak karena itu berarti token metode cocok dengan RFC sementara server tidak mengizinkannya untuk digunakan pada sumber daya ini. RFC 2616 § 10.4.1: [400 Bad Request] Permintaan tidak dapat dipahami oleh server karena sintaksis cacat. RFC 2616 § 10.4.6 [405 Metode Tidak Diizinkan] The metode yang ditentukan dalam Permintaan-Line tidak diperbolehkan untuk sumber daya diidentifikasi oleh Request-URI. Token getbukanlah metode HTTP dengan cara apa pun (lihat kutipan RFC 2616 § 5.1.1 di atas)
Xavier Lucas
@XavierLucas: menggunakan metode huruf kecil bukan kesalahan sintaks, periksa Bagian 5 RFC2616 . Dalam ABNF, extension-methodmiliki sintaksis tokenyang mencakup semua karakter alfanumerik dan beberapa simbol, bukan hanya metode yang secara khusus tercantum dalam RFC. Hampir setiap bagian dari HTTP dapat diperpanjang, selama klien dan server menyetujui bagaimana ekstensi itu diperluas, termasuk mendefinisikan metode huruf kecil Anda sendiri. Baris permintaan "get / HTTP / 1.1" secara sintaksis baik-baik saja, itu hanya melanggar RFC dalam nama metode yang harus peka huruf besar-kecil.
Lie Ryan
@ LieRyan ada di extension-methodsini untuk membiarkan pintu terbuka untuk RFC berikutnya, itu tidak di sini untuk mendapatkan metode Anda sendiri ditambahkan dari ruang lingkup RFC dan berpura-pura bahwa Anda menjalankan layanan yang sesuai dengan HTTP / 1.1. Jadi 400 harus dikembalikan karena belum ada metode yang muncul di RFC terbaru sehingga itu, hari ini, token yang tidak valid. Jika token itu valid mengenai daftar metode saat ini dan diimplementasikan sisi server tetapi tidak diizinkan maka 405 harus dikembalikan. A 501 harus dikembalikan jika metode ini valid tetapi tidak diimplementasikan di sisi server.
Xavier Lucas