Coloquei o seguinte no web.xml do meu aplicativo para tentar desabilitar 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, agora:
Se eu fizer uma solicitação com o método de DELETE
eu recebo um 403 de volta.
Se eu fizer uma solicitação com o método de delete
eu recebo um 403 de volta.
MAS
Se eu fizer uma solicitação com o método de DeLeTe
eu fico OK!
Como posso impedir que esses casos não façam diferença?
Edit: Estou testando-o com um 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
é uma caixa de texto onde estou digitando o nome do método. Quando existe um 403, é lançada uma exceção que é capturada no bloco de captura.
O cache_test.jsp contém:
<%
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
vai diferenciar maiúsculas de minúsculas reconhecer e converter métodos HTTP padrão para maiúsculas. Além disso, está documentado como permitindo apenas métodos HTTP padrão. A melhor opção é usar um fluxo TCP bruto (por exemplo, em netcat, PuTTY raw ou telnet, etc.).Respostas:
Independentemente do comportamento incorreto do Tomcat em relação ao padrão HTTP, você deve usar uma lista de permissões para permitir métodos específicos, em vez de uma lista negra.
Por exemplo, a lista de permissões a seguir bloqueará todos os métodos, exceto os que diferenciam maiúsculas de minúsculas
GET
eHEAD
.(Nota: requer Tomcat 7+. Os usuários de versões mais antigas precisarão investigar outras soluções, por exemplo, um filtro de servlet.)
Ref.
fonte
<auth-constraint />
e, em seguida, apenas permite tudo.http-method-omission
foi definido pela primeira vez na API do Servlet 3.0, implementada pelo Tomcat 7+: tomcat.apache.org/whichversion.html . Infelizmente, isso significa que isso não funcionará no Tomcat 6 e mais antigo (nota: 5 já é EOL). Você pode tentar a outra solução proposta na pergunta SO vinculada que recomenda definir doissecurity-constraint
s separados - não pude confirmar se um funciona em 7, portanto não o incluí nesta resposta.Bem, após testes rápidos em alguns servidores aleatórios com a
Server: Apache-Coyotte
assinatura do cabeçalho em suas respostas HTTP, parece que você está certo, pois o envioget / HTTP/1.1\r\nHost: <target_IP>\r\n\r\n
com uma conexão netcat simples funcionava sempre que um código HTTP 400 deveria ter sido recebido.Por exemplo :
Devo dizer que estou um pouco chocado aqui e não ficaria surpreso ao ver esse comportamento estendido a todos os métodos HTTP / 1.1 nesse caso.
Você deve preencher um relatório de bug na ferramenta de rastreamento de bugs e enviar um email para a lista de discussão apropriada, pois essa é uma violação feia da RFC 2616 (veja abaixo) com más conseqüências.
fonte
get
não é um HTTP método de qualquer maneira (veja o trecho da RFC 2616 § 5.1.1 acima)extension-method
tenha uma sintaxetoken
que inclua todos os caracteres alfanuméricos e alguns símbolos, não apenas os métodos listados especificamente na RFC. Quase todas as partes do HTTP são extensíveis, desde que o cliente e o servidor concordem como eles também devem ser estendidos, incluindo a definição de seus próprios métodos em minúsculas. A linha de solicitação "get / HTTP / 1.1" está sintaticamente correta, apenas viola a RFC no nome do método que diferencia maiúsculas de minúsculas.extension-method
Está aqui para deixar a porta aberta para as próximas RFCs, que não estão aqui para adicionar seus próprios métodos fora do escopo da RFC e fingir que você está executando serviços compatíveis com HTTP / 1.1. Portanto, um 400 deve ser retornado porque esse método ainda não apareceu na RFC mais recente, portanto, hoje é um token inválido. Se o token era válido em relação à lista de métodos atual e implementado no lado do servidor, mas não permitido, um 405 deve ser retornado. Um 501 deve ser retornado caso o método seja válido, mas não implementado no servidor.