28
28
import packaging_legacy .version
29
29
import pkg_resources
30
30
import requests
31
+ import sentry_sdk
31
32
import wtforms
32
33
import wtforms .validators
33
34
81
82
82
83
PATH_HASHER = "blake2_256"
83
84
85
+ COMPRESSION_RATIO_THRESHOLD = 10
86
+
84
87
85
88
# Wheel platform checking
86
89
@@ -670,6 +673,19 @@ def _is_valid_dist_file(filename, filetype):
670
673
# If our file is a zipfile, then ensure that it's members are only
671
674
# compressed with supported compression methods.
672
675
if zipfile .is_zipfile (filename ):
676
+ # Ensure the compression ratio is not absurd (decompression bomb)
677
+ compressed_size = os .stat (filename ).st_size
678
+ with zipfile .ZipFile (filename ) as zfp :
679
+ decompressed_size = sum (e .file_size for e in zfp .infolist ())
680
+ if decompressed_size / compressed_size > COMPRESSION_RATIO_THRESHOLD :
681
+ sentry_sdk .capture_message (
682
+ f"File { filename } ({ filetype } ) exceeds compression ratio "
683
+ "of {COMPRESSION_RATIO_THRESHOLD} "
684
+ "({decompressed_size}/{compressed_size})"
685
+ )
686
+ return False
687
+
688
+ # Check that the compression type is valid
673
689
with zipfile .ZipFile (filename ) as zfp :
674
690
for zinfo in zfp .infolist ():
675
691
if zinfo .compress_type not in {
@@ -680,6 +696,9 @@ def _is_valid_dist_file(filename, filetype):
680
696
681
697
tar_fn_match = _tar_filenames_re .search (filename )
682
698
if tar_fn_match :
699
+ # TODO: Ideally Ensure the compression ratio is not absurd
700
+ # (decompression bomb), like we do for wheel/zip above.
701
+
683
702
# Ensure that this is a valid tar file, and that it contains PKG-INFO.
684
703
z_type = tar_fn_match .group ("z_type" ) or ""
685
704
try :
0 commit comments