O apache mod_rewrite codifica duas vezes a string de consulta no redirecionamento

13

Encontramos um problema estranho (um bug, talvez?) Com o comportamento do Apache mod_rewrite ao passar por cadeias de consulta.

Para reproduzir, instalamos uma instalação limpa do Ubuntu (onírica) com a configuração padrão do Apache. Ativamos o mod_rewrite e, na configuração padrão do site, adicionamos o seguinte:

RewriteEngine on
RewriteRule ^/(.*)$ /r/$1 [R]

Para testar, usamos curl:

curl -I 'http://[ubuntu-machine]/a/b%20c?a%20b'

A saída relevante é:

HTTP/1.1 302 Found
Server: Apache/2.2.20 (Ubuntu)
Location: http://[ubuntu-machine]/r/a/b%20c?a%2520b

Como você pode ver, a string de consulta tem escape duplo, o que está errado. Alguém tem alguma idéia de como podemos corrigir isso? Tentamos algumas coisas:

  • Adicionando [NE]. Isso nos fornece a string de consulta correta, mas o caminho é sem escape, o que leva a novos problemas.
  • Adicionando [NE, B]. Isso parece funcionar, mas faz com que o /entre ae as bpartes do caminho sejam escapados.
  • Retirando o escape manual da cadeia de caracteres da consulta.

    RewriteCond %{QUERY_STRING} .*
    RewriteMap unescape int:unescape  
    RewriteRule ^(.*)$          $1?${unescape:%{QUERY_STRING}}
    

    No entanto, isso significa que não podemos distinguir entre, digamos, um &e um escape &na string de consulta.

Atualizar:

Este relatório de bug descreve o mesmo problema. O primeiro comentário está vinculado a um commit que aparentemente corrige o problema, mas como Pieter diz abaixo, não parece que ele esteja realmente corrigido.

Erik Hesselink
fonte

Respostas:

7

Isso parece ser um bug no Apache. Este relatório de erros é um pouco confuso, mas descreve seu problema exatamente:

https://issues.apache.org/bugzilla/show_bug.cgi?id=34602

Parece que eles estão cientes do problema. Embora o bug afirme que eles corrigiram, eu testei isso com o Apache 2.3.15, e o problema ainda parece estar lá. Observe também que o Apache 2.3 é uma versão beta, portanto, não adianta você mesmo que o tenha corrigido, até que o Apache 2.4 seja lançado.

Pieter
fonte
Parece que o Apache 2.4.10 ainda está fazendo isso, embora devesse ter sido corrigido no 2.4.1 .
Arjan
1
Ainda vejo o problema no 2.4.7 #
François