Por que um RewriteCond% {REQUEST_URI} interfere em uma segunda condição NOT?

1

Primeiro, a regra que funciona:

DirectoryIndex index.php
ErrorDocument 403 /form.html

RewriteCond %{REQUEST_URI} ^/index\.php$
RewriteCond %{REQUEST_METHOD} !POST
RewriteRule . - [F,L]

Isso significa que http://example.com e http://example.com/index.php só podem ser abertos por meio de POST .

Agora o problema

Eu adicionei este conjunto de regras adicionais:

RewriteCond %{REQUEST_URI} !^/index\.php$
RewriteRule . - [F,L]

Agora, envio um POST novamente para http://example.com , mas recebo este erro:

Forbidden

You don't have permission to access / on this server.
Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.

Isso não faz sentido, porque a regra NÃO deve capturar pedidos em index.php enviando um 403, mas ok, eu estendi a segunda regra da seguinte forma:

RewriteCond %{REQUEST_URI} !^/form\.html$
RewriteCond %{REQUEST_URI} !^/index\.php$
RewriteRule . - [F,L]

E enviar novamente um POST para o link não retorna 500, mas ainda recebo um 403?!

Atualização 1
Se eu remover o primeiro conjunto de regras, o segundo funciona sozinho como esperado. Isso significa que apenas http://example.com , http://example.com/index.php e http://example.com/form.html podem ser acessados.

Atualização 2
Se eu usar os dois conjuntos de regras e enviar meu POST para http://example.com/index.php , não receberei nenhum erro?!

Portanto, as regras só interferem se eu enviei um POST para o URL raiz. Mas por quê?

    
por mgutt 23.02.2017 / 16:55

1 resposta

0

RewriteCond %{REQUEST_URI} ^/index\.php$
RewriteCond %{REQUEST_METHOD} !POST
RewriteRule . - [F,L]

Assumindo que seu DirectoryIndex está definido como index.php e você não tem outras diretivas, esse parece ser o primeiro bloco de regras que está resultando no 403 Proibido ao acessar http://example.com/ . O acima só permite solicitações POST diretas para /index.php .

O padrão RewriteRule (um único ponto) acima evita que a regra seja processada para solicitações de http://example.com/ . mod_dir então inicia uma subrequição interna para /index.php . Observe que essa subrequicação realmente aparece como uma solicitação GET interna (que é a variável do servidor REQUEST_METHOD ), portanto, a condição acima ( !POST ) é bem-sucedida e a solicitação é proibida.

Seria preferível canonizar a solicitação e redirecionar externamente (308 - redirecionamento permanente preservando o método de solicitação) qualquer solicitação para /index.php to / . Você pode se concentrar em corresponder apenas a / e ignorar sub-solicitações.

# Exception for error document (before other directives)
RewriteRule ^form\.html$ - [L]

# Canonicalise URL and remove "index.php" if requested
RewriteRule %{REDIRECT_STATUS} ^$
RewriteRule ^index\.php$ / [R=308,L]

# Only allow POST requests to the document root
RewriteCond %{REQUEST_METHOD} !POST
RewriteRule ^$ - [F]

(Não é necessário usar L flag quando F é usado. L está implícito.)

Verifique se o cache do navegador está desimpedido antes do teste. (Pode ser preferível testar com redirecionamentos R=307 (temporários) para evitar o cache.)

RewriteCond %{REQUEST_URI} !^/index\.php$
RewriteRule . - [F,L]

Como você sugere, isso não entra em conflito com as regras acima, ele corresponde a algo diferente de / e /index.php (quando usado em .htaccess ). Portanto, isso proíbe o acesso a todos os outros URLs, independentemente do método de solicitação. (Como mencionado acima, parece ser a primeira regra que estava acionando o 403 ao acessar http://example.com/ .) Se você incluir uma exceção para seus documentos de erro, como acima, você não precisará adicionar uma condição adicional. / p>     

por 24.02.2017 / 01:37