Skip to content

Commit

Permalink
Fix handling of zip bombs when unzipping archives
Browse files Browse the repository at this point in the history
  • Loading branch information
Seldaek committed May 29, 2024
1 parent 3773f77 commit de5f7e3
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/Composer/Downloader/ZipDownloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ private function extractWithSystemUnzip(PackageInterface $package, string $file,
throw $processError;
}

if (str_contains($processError->getMessage(), 'zip bomb')) {
throw $processError;
}

if (!is_file($file)) {
$io->writeError(' <warning>'.$processError->getMessage().'</warning>');
$io->writeError(' <warning>This most likely is due to a custom installer plugin not handling the returned Promise from the downloader</warning>');
Expand Down Expand Up @@ -208,6 +212,26 @@ private function extractWithZipArchive(PackageInterface $package, string $file,
} else {
$retval = $zipArchive->open($file);
}

$totalSize = 0;
$archiveSize = filesize($file);
$totalFiles = $zipArchive->count();
if ($totalFiles > 0) {
for ($i = 0; $i < min($totalFiles, 5); $i++) {
$stat = $zipArchive->statIndex(random_int(0, $totalFiles - 1));
if ($stat === false) {
continue;
}
$totalSize += $stat['size'];
if ($stat['size'] > $stat['comp_size'] * 200) {
throw new \RuntimeException('Invalid zip file with compression ratio >99% (possible zip bomb)');
}
}
if ($archiveSize !== false && $totalSize > $archiveSize * 100 && $totalSize > 50*1024*1024) {
throw new \RuntimeException('Invalid zip file with compression ratio >99% (possible zip bomb)');
}
}

if (true === $retval) {
$extractResult = $zipArchive->extractTo($path);

Expand Down

0 comments on commit de5f7e3

Please sign in to comment.