TL; DR - a correção (que talvez você nem precise) é MUITO SIMPLES e está no final desta resposta.
Tentarei abordar suas perguntas específicas, mas seu equívoco sobre o que é PATH_INFO torna as perguntas um pouco erradas.
A primeira pergunta deve ser "O que é esse negócio de informações do caminho?"
Sua próxima pergunta deveria ter sido: "Como o PHP determina o que é PATH_INFO
e o que SCRIPT_FILENAME
é?"
- As versões anteriores do PHP eram ingênuas e tecnicamente nem suportavam
PATH_INFO
; portanto, o que era suposto ser PATH_INFO
colocado sobre o SCRIPT_FILENAME
qual, sim, é quebrado em muitos casos. Eu não tenho uma versão suficientemente antiga do PHP para testar, mas acredito que ela tenha SCRIPT_FILENAME
visto o shebang inteiro: "/path/to/script.php/THIS/IS/PATH/INFO" no exemplo acima (prefixado com a docroot como de costume).
- Com o cgi.fix_pathinfo ativado, o PHP agora encontra corretamente "/ THIS / IS / PATH / INFO" para o exemplo acima e o coloca
PATH_INFO
e SCRIPT_FILENAME
obtém apenas a parte que aponta para o script que está sendo solicitado (prefixado com a docroot, é claro).
- Nota: quando o PHP realmente deu suporte
PATH_INFO
, eles tiveram que adicionar uma configuração para o novo recurso, para que as pessoas que executavam scripts que dependiam do comportamento antigo pudessem executar novas versões do PHP. É por isso que existe até um comutador de configuração. Deveria ter sido incorporado (com o comportamento "perigoso") desde o início.
Mas como o PHP sabe qual parte é o script e qual é a informação do caminho? E se o URI for algo como:
http://example.com/path/to/script.php/THIS/IS/PATH/INFO.php?q=foo
- Essa pode ser uma pergunta complexa em alguns ambientes. O que acontece no PHP é que ele encontra a primeira parte do caminho do URI que não corresponde a nada na documentação do servidor. Neste exemplo, ele vê que em seu servidor você não possui "/docroot/path/to/script.php/THIS", mas certamente você tem "/docroot/path/to/script.php", então agora o
SCRIPT_FILENAME
foi determinado e PATH_INFO
recebe o resto.
- Portanto, agora o bom exemplo do perigo detalhado nos documentos Nginx e na resposta de Hrvoje Špoljar (você não pode ser exigente com um exemplo tão claro) fica ainda mais claro: dado o exemplo de Hrvoje (" http: // example. com / foo.jpg / nonexistent.php "), o PHP vê um arquivo na sua docroot" /foo.jpg ", mas não vê nada chamado" /foo.jpg/nonexistent.php "então
SCRIPT_FILENAME
obtém" /foo.jpg " (novamente, prefixado com docroot) e PATH_INFO
obtém "/nonexistent.php".
Por que e como isso pode ser perigoso agora deve ficar claro:
- O servidor da web realmente não é culpado - é apenas um proxy do URI para o PHP, que inocentemente descobre que "foo.jpg" na verdade contém conteúdo PHP, então ele é executado (agora você foi pwned!). Isso NÃO é específico do Nginx em si.
- O problema REAL é que você permite que o conteúdo não confiável seja carregado em algum lugar sem sanitização e permite outras solicitações arbitrárias no mesmo local, que o PHP executa felizmente quando pode.
O Nginx e o Apache podem ser construídos ou configurados para impedir solicitações usando esse truque, e há muitos exemplos de como fazer isso, inclusive na resposta do usuário2372674 . Este artigo do blog explica bem o problema, mas está faltando a solução certa.
No entanto, a melhor solução é garantir que o PHP-FPM esteja configurado corretamente para que ele nunca execute um arquivo, a menos que termine com ".php". Vale a pena notar que as versões recentes do PHP-FPM (~ 5.3.9 +?) Têm isso como padrão, então esse perigo não é mais um problema.
A solução
Se você possui uma versão recente do PHP-FPM (~ 5.3.9 +?), Não precisa fazer nada, pois o comportamento seguro abaixo já é o padrão.
Caso contrário, encontre o www.conf
arquivo php-fpm (talvez /etc/php-fpm.d/www.conf
dependa do seu sistema). Certifique-se de ter o seguinte:
security.limit_extensions = .php
Novamente, isso é padrão em muitos lugares hoje em dia.
Observe que isso não impede que um invasor carregue um arquivo ".php" para uma pasta de uploads do WordPress e execute-o usando a mesma técnica. Você ainda precisa ter uma boa segurança para seus aplicativos.