fix: audit — json try/except, ZIP-bomb drhider, classify reset only processing
Deploy contracts-flask / validate (push) Successful in 0s
Deploy contracts-flask / validate (push) Successful in 0s
This commit is contained in:
@@ -251,25 +251,29 @@ class TwoPassObfuscator:
|
||||
self._sorted_keys.clear()
|
||||
|
||||
def _expand_zips(self, files: List[Tuple[str, bytes, str]]) -> List[Tuple[str, bytes, str]]:
|
||||
"""Распаковать ZIP-файлы, заменив их содержимым. Остальные файлы — как есть."""
|
||||
"""Распаковать ZIP-файлы, заменив их содержимым. Остальные файлы — как есть.
|
||||
Защита от ZIP-бомб: ratio + накопительный размер (как в compare/unzip.py)."""
|
||||
result = []
|
||||
for fname, content, ctype in files:
|
||||
if fname.lower().endswith('.zip'):
|
||||
try:
|
||||
with zipfile.ZipFile(io.BytesIO(content)) as zf:
|
||||
total_size = sum(info.file_size for info in zf.infolist())
|
||||
if total_size > 500 * 1024 * 1024: # 500 MB
|
||||
log.warning("ZIP too large, skipping expansion: %s", fname)
|
||||
result.append((fname, content, ctype))
|
||||
continue
|
||||
if len(zf.infolist()) > 500:
|
||||
log.warning("ZIP too many files, skipping: %s", fname)
|
||||
result.append((fname, content, ctype))
|
||||
continue
|
||||
total_uncompressed = 0
|
||||
for info in zf.infolist():
|
||||
if info.is_dir():
|
||||
continue
|
||||
# cp437 → utf8 (как в services/unzip.py)
|
||||
# ZIP bomb: ratio check
|
||||
if info.compress_size > 0:
|
||||
ratio = info.file_size / info.compress_size
|
||||
if ratio > 100:
|
||||
log.warning("ZIP bomb ratio %.0f:1, skipping: %s", ratio, fname)
|
||||
result.append((fname, content, ctype))
|
||||
break
|
||||
# cp437 → utf8 (как в compare/unzip.py)
|
||||
name = info.filename
|
||||
try:
|
||||
name = name.encode("cp437").decode("utf-8", errors="replace")
|
||||
@@ -280,6 +284,10 @@ class TwoPassObfuscator:
|
||||
if not name or name.endswith("/") or ".." in name or "/" in name or "\\" in name:
|
||||
continue
|
||||
inner_data = zf.read(info)
|
||||
total_uncompressed += len(inner_data)
|
||||
if total_uncompressed > 500 * 1024 * 1024: # 500 MB
|
||||
log.warning("ZIP uncompressed limit exceeded, stopping: %s", fname)
|
||||
break
|
||||
result.append((name, inner_data, ""))
|
||||
except Exception as e:
|
||||
log.warning("Failed to expand ZIP %s: %s", fname, e)
|
||||
|
||||
Reference in New Issue
Block a user