Habilitar o escape duplo é perigoso?

136

Eu tenho um aplicativo ASP.NET MVC com uma rota que permite pesquisar coisas via / search / <searchterm>.

Quando eu forneço "search / abc", ele funciona bem, mas quando eu forneça "/ search / a + b + c" (codificado corretamente por URL), o IIS7 rejeita a solicitação com o Erro HTTP 404.11 ( O módulo de filtragem de solicitação está configurado para negar uma solicitação que contém uma sequência de escape duplo ). Primeiro de tudo, por que isso acontece? Parece apenas lançar o erro se fizer parte da URL, mas não como parte de uma string de consulta (/ transmit? Q = a + b + c funciona bem).

Agora eu poderia habilitar solicitações de escape duplo na seção de segurança do meu web.config, mas hesito em fazê-lo, pois não entendo as implicações e nem por que o servidor rejeitaria a solicitação "a + b + c" como parte do URL, mas aceite como parte de uma sequência de consultas.

Alguém pode explicar e dar alguns conselhos sobre o que fazer?

Alex
fonte
7
Também tentei a opção possivelmente mais correta de chamar Server.Url Path Encode e acabei com /search/a%2520b%2520ca marcação que levou a um erro adorável "Um valor Request.Path potencialmente perigoso foi detectado no cliente (%)". Parece que você não pode vencer.
Zhaph - Ben Duguid

Respostas:

158

Editar: ênfase adicionada às seções relevantes.

Basicamente: o IIS está sendo excessivamente paranóico. Você pode desativar essa verificação com segurança se não estiver fazendo algo particularmente imprudente com os dados decodificados pela URI (como gerar URIs do sistema de arquivos local via concatenação de cadeias).

Para desativar a verificação, faça o seguinte ( daqui ): (veja meu comentário abaixo para saber o que significa escape duplo).

<system.webServer>
    <security>
        <requestFiltering allowDoubleEscaping="true"/>
    </security>
</system.webServer>

Se o símbolo de adição for um caractere válido em uma entrada de pesquisa, será necessário habilitar "allowDoubleEscaping" para permitir que o IIS processe essa entrada a partir do caminho do URI.

Por fim, uma solução alternativa muito simples, se limitada, é simplesmente evitar '+' e usar '% 20'. De qualquer forma, o uso do símbolo '+' para codificar um espaço não é uma codificação de URL válida , mas específica para um conjunto limitado de protocolos e provavelmente amplamente suportado por razões de compatibilidade com versões anteriores. Se apenas para fins de canonização, é melhor codificar espaços como '% 20'; e isso evita o problema do IIS7 (que ainda pode surgir para outras seqüências, como% 25ab.)

Eamon Nerbonne
fonte
3
Eu desabilitaria a verificação. É um aborrecimento e não fornece segurança extra para a maioria dos aplicativos.
Eamon Nerbonne
3
Você tem um link / referência que é praticamente seguro desativar a fuga dupla? Além disso, o que exatamente essa medida de segurança impede que aconteça?
Alex
15
Se um uri for escapado duas vezes, os componentes do uri sem escape podem conter caracteres reservados e, portanto, (partes de) o uri sem escape pode ser um uri válido. Em resumo, se você usar a string uri sem escape para construir novas URLs - em particular caminhos do sistema de arquivos - e não conseguir escapar corretamente do novo caminho, poderá permitir a injeção do caminho. A injeção de caminho pode permitir que um invasor induza seu programa a processar dados que não deveria, ou confunda-o ao pensar que duas uri são diferentes quando na verdade são idênticas, mas simplesmente codificadas de maneira diferente.
Eamon Nerbonne
4
@Stijn: Sim: isso é seguro . Tudo o que essa verificação faz é filtrar solicitações que possam ser mal interpretadas pelo código de buggy (especialmente se você decodificar ou construir o Uri via string-concat e sem codificação adequada). Você não está fazendo nenhum tipo de processamento, portanto é praticamente seguro da sua parte. Qualquer bug precisaria estar no código básico do IIS, e acho que podemos assumir com segurança que já foi testado em batalhas muito, muito profundas. Novamente, essa verificação não é nada sofisticada, apenas se baseia em coisas que podem ser decodificadas e, em seguida, parecem uma uri codificada .
Eamon Nerbonne
2

Gostaria apenas de acrescentar algumas informações à resposta de Eamon Nerbonne relacionadas à parte " o que fazer " da sua pergunta (sem explicar os porquês).
Você também pode alterar facilmente as configurações de um aplicativo específico com

  1. abrir o console com direitos de administrador (Iniciar - cmd - clique com o botão direito do mouse, Executar como administrador)
  2. digitando o seguinte (extraído daqui: http://blogs.iis.net/thomad/archive/2007/12/17/iis7-rejecting-urls-containing.aspx ):

    %windir%\system32\inetsrv\appcmd set config "YOURSITENAME" -section:system.webServer/security/requestfiltering -allowDoubleEscaping:true

    (você pode, por exemplo, substituto YOURSITENAMEcom Default Web Sitepara aplicar esta regra para o site padrão)

  3. Entre, pronto.

Um exemplo:

  1. primeiro tive o mesmo problema: Erro HTTP 404.11 - O módulo de filtragem de solicitações está configurado para negar uma solicitação que contém uma sequência de escape duplo.
  2. Digitando o texto mencionado acima: Drupal7-another Solução para o erro HTTP 404.11 - O módulo de filtragem de solicitações está configurado para negar uma solicitação que contém uma sequência de escape duplo.
  3. Agora funciona como esperado: Solução para o erro HTTP 404.11 - O módulo de filtragem de solicitações está configurado para negar uma solicitação que contém uma sequência de escape duplo.
Sk8erPeter
fonte
1

Você já pensou em ter o URL de pesquisa como '/ search / a / b / c'?

Você precisaria configurar uma rota como

search/{*path}

E, em seguida, extraia os valores da pesquisa da string do caminho na ação.

HTHs
Charles

Charlino
fonte
O problema é que outros caracteres codificados em URL (incluindo o próprio '/') podem fazer parte da pesquisa.
Alex
Não foi possível codificar todos os '/' que fazem parte da pesquisa para '% 2F'?
Charlino 21/09/09
0

Eu corri para isso no IIS 7.5 fazendo um Server.TransferRequest () em um aplicativo.

A codificação do nome do arquivo causou o problema de escape duplo, mas se não o codificasse, ocorreria o erro "potencialmente perigoso Request.Path" .

Colocar um protocolo qualquer, mesmo um vazio, na URL que passo para Server.TranferRequest () resolveu o problema.

Não funciona:

context.Server.TransferRequest("/application_name/folder/bar%20bar.jpg");

Trabalho:

context.Server.TransferRequest("://folder/bar%20bar.jpg");
mhenry1384
fonte