Skip to content

Três outros ZIPs são extraídos com os caminhos reescritos em silêncio #242

Closed

Description

@matbrgz

Irmão do que foi consertado em #233/#239, nos outros três lugares que extraem ZIP enviado por alguém:

  • app/Services/BocaImporterService.php:48
  • app/Http/Controllers/Api/ProblemController.php:97
  • app/Services/ProblemPackageService.php:36

O que medi

ZipArchive::extractTo() não deixa escapar do diretório de destino. Com PHP 8.5 / libzip 1.22.8:

entrada no ZIP onde caiu
../a.txt alvo/a.txt
../../b.txt alvo/b.txt
x/../../c.txt alvo/c.txt
/tmp/abs-d.txt alvo/tmp/abs-d.txt

Nada saiu do destino. Não é fuga de diretório.

O que sobra

O PHP resolve a travessia reescrevendo o caminho em silêncio. Um pacote com x/../../data/secret/01.ans grava em data/secret/01.ans e passa por cima de um arquivo legítimo do próprio pacote — sem erro, sem aviso.

Num pacote de problema isso troca um caso de teste. O pacote é aceito, o problema é importado, e o sintoma aparece longe da causa: uma submissão correta reprovada durante a prova.

O conserto

O mesmo de ProblemPackageImportController::nomeQueEscapa(): percorrer getNameIndex() antes de extrair e recusar o pacote inteiro se algum nome for absoluto ou tiver um segmento .. — com a frase dizendo qual nome. Vale extrair para um lugar comum aos quatro em vez de copiar.

Não depender da limpeza do libzip também é o que mantém a garantia verdadeira se a versão da imagem mudar.

Cuidado ao consertar

Um nome de arquivo com dois pontos no meio (a..b.pdf) é legítimo. Uma guarda que o recusasse rejeitaria pacotes bons, e a recusa não diria por quê — vale um controle positivo no teste.

Activity

  1. matbrgz commented on Sep 16, 2026

    @matbrgz
    MemberAuthor

    Consertado em #243.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions