Puse lo siguiente en el web.xml de mi aplicación para intentar no permitir PUT, DELETE, etc .:
<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, entonces ahora:
Si hago una solicitud con el método de DELETE
, obtengo un 403 de vuelta.
Si hago una solicitud con el método de delete
, obtengo un 403 de vuelta.
PERO
Si hago una solicitud con el método de DeLeTe
me sale bien!
¿Cómo puedo hacer que no permita estas mayúsculas y minúsculas?
Editar: lo estoy probando con un programa 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
es un cuadro de texto donde estoy escribiendo el nombre del método. Cuando hay un 403, se lanza una excepción que queda atrapada en el bloque catch.
Cache_test.jsp contiene:
<%
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());
%>
HttpWebRequest
se mayúsculas y minúsculas reconocer y convertir métodos HTTP estándar a mayúsculas. Además, se documenta que solo permite métodos HTTP estándar. La mejor opción es utilizar una secuencia TCP sin procesar (por ejemplo, en netcat, o PuTTY raw, o telnet, etc.).Respuestas:
Independientemente del comportamiento incorrecto de Tomcat con respecto al estándar HTTP, debe usar una lista blanca para permitir métodos específicos en lugar de una lista negra.
Por ejemplo, la siguiente lista blanca bloqueará todos los métodos, excepto los que distinguen entre mayúsculas
GET
y minúsculas yHEAD
.(Nota: requiere Tomcat 7+. Aquellos que usen versiones anteriores tendrán que investigar otras soluciones, por ejemplo, un filtro de servlet).
Árbitro
fuente
<auth-constraint />
y luego simplemente permite todo.http-method-omission
se definió por primera vez en Servlet API 3.0, implementado por Tomcat 7+: tomcat.apache.org/whichversion.html . Desafortunadamente, esto significa que esto no funcionará en Tomcat 6 y versiones anteriores (nota: 5 ya es EOL). Puede probar la otra solución propuesta en la pregunta SO vinculada que recomienda establecer dossecurity-constraint
s separadas . No pude confirmar que una funcione en 7, por lo que no la incluí en esta respuesta.Bueno, después de realizar pruebas rápidas en algunos servidores aleatorios con
Server: Apache-Coyotte
firma de encabezado en sus respuestas HTTP, parece que tiene razón, ya que el envíoget / HTTP/1.1\r\nHost: <target_IP>\r\n\r\n
con una conexión netcat simple funcionó cada vez que se debería haber recibido un código 400 HTTP.Por ejemplo :
Debo decir que estoy un poco sorprendido aquí y no me sorprendería ver que ese comportamiento se extendió a todos los métodos HTTP / 1.1 en tal caso.
Debe completar un informe de errores en su herramienta de seguimiento de errores y enviar un correo electrónico a la lista de correo apropiada porque es una violación fea del RFC 2616 (ver más abajo) con malas consecuencias.
fuente
get
no es un método HTTP de ninguna manera (vea el extracto de RFC 2616 § 5.1.1 arriba)extension-method
tenga una sintaxistoken
que incluya todos los caracteres alfanuméricos y algunos símbolos, no solo los métodos enumerados específicamente en el RFC. Casi todas las partes de HTTP son extensibles, siempre que el cliente y el servidor acuerden cómo se extenderán, incluida la definición de sus propios métodos en minúsculas. La línea de solicitud "get / HTTP / 1.1" está sintácticamente bien, solo viola el RFC en ese nombre de método que distingue entre mayúsculas y minúsculas.extension-method
está aquí para dejar la puerta abierta a los próximos RFC, no está aquí para agregar sus propios métodos fuera del alcance de RFC y pretender que está ejecutando servicios compatibles con HTTP / 1.1. Por lo tanto, se debe devolver un 400 porque aún no ha aparecido dicho método en la última RFC, por lo que hoy es un token no válido. Si el token era válido con respecto a la lista de métodos actual e implementado en el lado del servidor, pero no estaba permitido, se debería devolver un 405. Se debe devolver un 501 en caso de que el método sea válido pero no esté implementado en el lado del servidor.