You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Três outros ZIPs são extraídos com os caminhos reescritos em silêncio #242
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
Recusa caminho que sai do próprio pacote nos outros três ZIPs (issue #…
matbrgz commentedon Sep 16, 2026
Consertado em #243.