Insegurança comum na configuração do PHP?

10

Eu trabalho com a administração de sistemas em uma universidade e apenas me deparei com algo que provavelmente é comum, mas foi um choque para mim.

Todos os diretórios public_html e áreas da web são armazenados em afs, com permissões de leitura para os servidores da web. Como os usuários podem ter scripts php em public_html, isso significa que eles podem acessar os arquivos uns dos outros a partir do php (e os principais arquivos da web!).

Isso não apenas torna totalmente inútil a proteção por senha .htaccess, como também permite que os usuários leiam arquivos de origem php contendo senhas do banco de dados mysql e informações sensíveis semelhantes. Ou, se descobrirem que outras pessoas têm diretórios nos quais os servidores da Web têm acesso de gravação (por exemplo, para registros pessoais ou para salvar dados de formulários enviados), eles podem armazenar arquivos nessas contas.

Um exemplo simples:

<?
  header("Content-type: text/plain");
  print file_get_contents("/afs/example.com/home/smith/public_html/.htpasswd"); 
?>

Isso é um problema comum? E como você normalmente resolve isso?

ATUALIZAR:

Obrigado pela contribuição. Infelizmente, parece que não há uma resposta simples. Em um grande ambiente compartilhado como esse, provavelmente os usuários não devem ter tanta escolha. A melhor abordagem que posso pensar é definir "open_basedir" na configuração principal de todos os diretórios "public_html", executar o suphp e permitir apenas php limpo (sem scripts cgi, executando comandos externos com backticks etc.).

Mudar a política como essa quebraria muitas coisas e possivelmente faria com que os usuários pegassem seus forcados e nos perseguissem ... Vou discutir isso com meus colegas e atualizar aqui se tomarmos uma decisão sobre como alterar a configuração.

Pontus
fonte
Esta é uma pergunta interessante. Tenho certeza de que nos principais provedores de hospedagem compartilhada (por exemplo, DreamHost), isso não é possível. Mas eu estaria interessado em como eles se protegem disso. suphp, como cstamas mencionou, parece uma boa solução, mas é isso que a maioria dos provedores de hospedagem usa?
Lèse majesté
1
Eu usei a open_basedirsolução abaixo na produção compartilhada sistemas de hospedagem, mas nós dividir todo mundo em seu próprio vhost - Não tenho certeza se ele funciona para diretórios individuais ...
voretaq7

Respostas:

8

Pode-se usar o suphp, que executa o script php com o uid de seu proprietário.

http://www.suphp.org

cstamas
fonte
Provavelmente, isso não resolverá o problema acima (pelo menos em um ambiente de hospedagem compartilhado. Os arquivos .htpasswd geralmente são de propriedade do usuário que possui o site e o grupo (apache) ou o mundo (porque os usuários não sabem / se preocupam com a segurança) legíveis, por isso mesmo com suPHP eles seriam capazes de ler esses arquivos)
voretaq7
@ voretaq7: Várias outras restrições podem ser aplicadas. Tanto quanto me lembro, você pode até negar o acesso a arquivos que não possui. Portanto, isso exclui o ataque acima.
Cstamas
Sei que você pode restringir permissões em arquivos ("Não pode ser gravável por grupo / outro / ninguém"), mas não sei como bloquear leituras além das permissões do FS. Eles têm check_vhost_docroot, mas AFAIK que só se aplica para o script que está sendo executado (posso estar errado sobre isso?)
voretaq7
1
Não tenho certeza se o suphp é uma boa solução em um ambiente como este. Um usuário pode ter todos os tipos de permissões que o usuário www não possui. Um invasor que encontrasse uma maneira de acessar o php poderia encontrar chaves ssh ou keytabs ou alterar os scripts de login de um usuário para criar backdoors. E as configurações de "vhosts" não são tão úteis, pois os diretórios public_html estão disponíveis por meio de "/ ~ nome de usuário" no host virtual principal. Estou pensando que talvez scripts em public_html devam estar completamente desativados.
Pontus
4

Minha sugestão seria limitar o acesso do PHP aos arquivos (por meio de open_basedirdiretivas semelhantes, por host): Você deseja que os usuários possam abrir / ler / gravar arquivos em sua raiz da web e, talvez, um nível acima dela (para rascunho espaço), mas não um diretório onde estariam armazenando, por exemplo, htpasswdarquivos.

Uma estrutura de diretórios como:

/Client
    /auth
    /site
        /www_root
        /www_tmp

Atenderia a esse requisito: open_basedirpoderia ser apontado com /Client/sitesegurança e os htpasswdarquivos armazenados /Client/auth(com .htaccessarquivos ou httpd.confmodificados para apontar para o local apropriado).
Isso evita que seus clientes abram arquivos de outras pessoas, e, como benefício, usuários mal-intencionados não conseguem ler as coisas /Client/auth(ou qualquer outra coisa no seu sistema, como /etc/passwd:-)

Veja http://php.net/manual/en/ini.core.php para mais detalhes sobre a implementação open_basedir e per-vhost.

voretaq7
fonte
1
suphpcomo observado por cstamas também é uma boa idéia em um ambiente de hospedagem compartilhada - há um pouco de sobrecarga na configuração, mas eu diria que o ganho de segurança vale totalmente a pena. Com falta de sandboxing em todos os seus sites PHP, algo como um FreeBSD Jail ou uma máquina virtual dedicada que é uma das maiores vitórias de segurança.
voretaq7
"open_basedir" parece ser uma maneira simples de separar os principais arquivos da web dos arquivos do usuário, desde que "public_html" seja servido por meio de seu próprio host virtual. Mas não protege os usuários um do outro, pois eles não têm seus próprios hosts virtuais. Direita?
Pontus
Eu não tentei configuração open_basedirdentro de um <Directory> directiva, mas eu acho que deveria ser permitido ( "tentar e ver" - o pior que pode fazer não é trabalho :)
voretaq7
1
Até agora, parece que open_basedir é o que a maioria dos hosts comerciais da web usa (geralmente os assinantes têm seus próprios domínios pagos ou recebem um subdomínio gratuito), mas para páginas iniciais baseadas em diretório, como em uma instituição acadêmica, o suphp parece ser a melhor resposta.
Lèse majesté
1

Não, não é um problema comum, porque a maioria dos hosts compartilhados definiria uma configuração open_basedir no arquivo htaccess no diretório public_html de cada usuário (ou no vhost se cada usuário tiver seu próprio vhost).

por exemplo, do arquivo .htaccess:

# Assuming these are not set globally - its good practice to limit:
  php_flag magic_quotes_gpc off
  php_flag magic_quotes_runtime off
  php_flag register_globals off
  php_flag short_open_tag off
  php_value max_execution_time 60

# These set the user-specific paths
  php_value open_basedir /afs/example.com/home/smith:/usr/share/php/include
  php_value session.save_path /afs/example.com/home/smith/tmp
  php_value upload_tmp_dir /afs/example.com/home/smith/tmp

Mas certifique-se de definir as permissões corretas no arquivo .htaccess para impedir que o usuário altere o open_basedir (se eles tentarem substituí-lo no subdir / .htaccess, ele não funcionará - mas você provavelmente deve testá-lo) .

HTH

C.

symcbean
fonte
2
Isso pode ajudar a oferecer alguma proteção inicial a novas contas. Mas o fato de um usuário não poder editá-lo pode tornar tentador remover o arquivo .htaccess (o que ele pode fazer, pois requer apenas acesso de gravação ao diretório public_html) e criar o seu próprio. Adicionar um bloco "<Directory>" na configuração principal de cada usuário funcionaria, mas aqui eles ainda podem voltar aos comandos externos do php, o que significa que o open_basedir é facilmente contornado.
Pontus
@ Pontus: bom argumento para excluir o arquivo (não tenho certeza se o afs suporta o atributo de arquivo imutável). Eu teria dado +1 se você dissesse que a execução do servidor da web na cadeia chroot protegeria contra todos os tipos de vulnerabilidades de execução de programas.
symcbean
1

O AFS ignora permissões simples de usuário unix. O suPHP executa um setuid antes de executar o programa php, mas isso não fornece ao processo os tokens kerberos necessários para acessar o AFS e fica restrito às suas permissões. O suPHP precisaria ser modificado de alguma maneira para obter esses tokens antes que ele pudesse se apresentar ao sistema AFS como esse usuário. Até onde eu sei, isso não foi feito. (Na verdade, eu encontrei essa pergunta ao procurar se alguém havia feito isso.)

Charles B
fonte