Problemas Potenciais de Segurança com o ZipArchive do PHP

9

Eu quero permitir que os membros tenham a opção de enviar conteúdo usando um arquivo zip. Uma vez carregado, eu quero usar a classe ZipArchive do PHP para descompactar o conteúdo do arquivo zip em um diretório, e depois mover os arquivos para o nosso sistema.

Estou preocupado com os potenciais riscos de segurança, e não consigo encontrar nenhuma documentação no php.net. O primeiro (Bem, o único) risco que vem à mente, é alguém criando um arquivo zip com caminhos relativos como "../../etc/passwd" (Se eles assumirem que eu descomprimo o arquivo em / tmp / somedir).

Na verdade, estou tendo dificuldade em criar um caminho relativo em um arquivo zip, por isso não posso testar se isso seria possível. Eu também não consigo encontrar qualquer maneira de extrair o conteúdo do arquivo zip usando ZipArchive, e tê-lo ignorar diretórios (descomprimir todos os arquivos, mas não criar a estrutura de diretório dentro do zip).

Alguém pode me dizer se tal exploração é possível, e / ou como ignorar a estrutura de diretório em um arquivo zip usando o ZipArchive?

    
por mellowsoon 12.07.2011 в 17:47
fonte

4 respostas

0

No final, estou indo com a solução de Pekka, de usar o utilitário unzip da linha de comando. Ele fornece opções para ignorar diretórios no arquivo zip. As preocupações que outros apontaram não são um problema aqui. Depois que os arquivos são descompactados, nós os adicionamos ao sistema usando o mesmo processo que os nossos envios regulares, o que significa que cada arquivo é examinado usando as medidas de segurança que já temos em vigor.

    
por mellowsoon 12.07.2011 / 20:42
fonte
3

Eu tive as mesmas preocupações e dei uma olhada no código-fonte do PHP 5.3 onde encontrei isto:

/* Clean/normlize the path and then transform any path (absolute or relative)
         to a path relative to cwd (../../mydir/foo.txt > mydir/foo.txt)
 */
virtual_file_ex(&new_state, file, NULL, CWD_EXPAND TSRMLS_CC);
path_cleaned =  php_zip_make_relative_path(new_state.cwd, new_state.cwd_length);
if(!path_cleaned) {
    return 0;
}

Parece ótimo para mim. Finalize o PHP e veja ./ext/zip/php_zip.c para detalhes.

    
por adonig 03.01.2014 / 01:54
fonte
2

Pergunta interessante, mas peço que você faça isso de uma maneira diferente. Eu recomendo que você execute o seu processo web com menos privilégios em uma prisão chroot. Supondo que você faça isso, a pior coisa que pode acontecer é que seu site seja desfigurado e, em seguida, você restaure um backup e faça algumas perícias para preencher esse buraco específico. Novos buracos são descobertos constantemente, você terá um tempo muito difícil garantindo completamente seu site indo atrás de palpites como estes. Minimizar o sandbox do atacante realmente é um longo caminho.

    
por Josh 12.07.2011 / 19:59
fonte
1

Você precisa garantir que o conteúdo extraído não seja servido diretamente pelo servidor de aplicativos. Então, se alguém tem um arquivo php em seu arquivo que ele não pode executá-lo através do seu servidor.

Outra coisa é que você deve evitar que as coisas sejam incluídas no conteúdo gerado pelo usuário. Mas isso deve ser considerado também sem ter arquivos zip no lugar.

    
por fyr 12.07.2011 / 17:53
fonte