Houve um monte de falar sobre um problema de segurança em relação à cgi.fix_pathinfo
opção PHP usado com Nginx (geralmente PHP-FPM, CGI rápido).
Como resultado, o arquivo de configuração nginx padrão costumava dizer:
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
No entanto, agora, o wiki "oficial" do Nginx afirma que PATH_INFO pode ser tratado corretamente sem desativar a opção PHP acima. E daí?
Questões
- Você pode explicar claramente o que
cgi.fix_pathinfo
faz? (o documento oficial diz apenas : "Para obter mais informações sobre PATH_INFO, consulte as especificações CGI") - O que o PHP realmente fará com essas
PATH_INFO
eSCRIPT_FILENAME
variáveis? - Por que e como isso pode ser perigoso com o Nginx? ( exemplos detalhados )
- O problema ainda existe nas versões recentes desses programas?
- O Apache é vulnerável?
Estou tentando entender o problema a cada etapa. Por exemplo, não entendo por que usar o soquete php-fpm Unix poderia evitar esse problema.
Respostas:
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?"
Informações do caminho são coisas após o script em um URI (devem começar com uma barra, mas terminam antes dos argumentos da consulta, que começam com a
?
). O último parágrafo da seção de visão geral do artigo da Wikipedia sobre CGI resume bem. Abaixo doPATH_INFO
"/ THIS / IS / PATH / INFO":http://example.com/path/to/script.php/THIS/IS/PATH/INFO?query_args=foo
Sua próxima pergunta deveria ter sido: "Como o PHP determina o que é
PATH_INFO
e o queSCRIPT_FILENAME
é?"PATH_INFO
; portanto, o que era suposto serPATH_INFO
colocado sobre oSCRIPT_FILENAME
qual, sim, é quebrado em muitos casos. Eu não tenho uma versão suficientemente antiga do PHP para testar, mas acredito que ela tenhaSCRIPT_FILENAME
visto o shebang inteiro: "/path/to/script.php/THIS/IS/PATH/INFO" no exemplo acima (prefixado com a docroot como de costume).PATH_INFO
eSCRIPT_FILENAME
obtém apenas a parte que aponta para o script que está sendo solicitado (prefixado com a docroot, é claro).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
SCRIPT_FILENAME
foi determinado ePATH_INFO
recebe o resto.SCRIPT_FILENAME
obtém" /foo.jpg " (novamente, prefixado com docroot) ePATH_INFO
obtém "/nonexistent.php".Por que e como isso pode ser perigoso agora deve ficar claro:
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: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.
fonte
SCRIPT_FILENAME
é, por que há umafastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
linha no meunginx
conf? Ele substitui o esforço do PHP para descobrir o valor deSCRIPT_FILENAME
si mesmo?security.limit_extensions
? Eu tenteiphpinfo()
,ini_get(security.limit_extensions)
eini_get_all()
sem sucesso.Essencialmente, sem isso, você pode fazer upload de arquivos com código php chamado 'foo.jpg' para o servidor da web; solicite-o como http: //domain.tld/foo.jpg/nonexistent.php e a pilha do servidor da Web digitará erroneamente oh; isto é um PHP; Eu preciso processar isso, ele falhará ao encontrar foo.jpg / nonexistent.php, então ele voltará a foo.jpg e processará foo.jpg como código php. Isso é perigoso, pois abre o sistema para uma invasão muito fácil; qualquer aplicativo da Web que permita o upload de imagens, por exemplo, torna-se uma ferramenta para enviar backdoor.
Em relação ao uso de php-fpm com soquete unix para evitá-lo; IMO não vai resolver o problema.
fonte
cgi.fix_pathinfo
é perigoso, porque a configuração padrão é segura (ela executará apenas os arquivos com a extensão).php-fpm
.php
No wiki do Nginx como medida de segurança
está incluído no bloco de localização. Em outros tutoriais
é usado, o que deve fazer o mesmo, mas pode causar problemas de acordo com o wiki do Nginx. Com essas opções,
cgi.fix_pathinfo=1
não deve mais ser um problema. Mais informações podem ser encontradas aqui .fonte