A zip-bomb tucked inside a media file makes a desktop converter sit down and cry
GPAC is an open-source multimedia framework — MP4Box, the gpac CLI, and the libgpac library used by transcoders, packagers, and a few CDN ingest tools. The flaw lives in src/utils/base_encoding.c inside the ISOBMFF parser path: when GPAC inflates highly compressed metadata embedded in a crafted file, it does not bound the output relative to the input, so a tiny payload expands until memory or CPU is exhausted. Affected versions: GPAC up to and including 26.02.0. Fix: commit 297f2d8d1f493d8b241330533cd47f7da758aeb3, which aborts inflation when output exceeds 32× input.
Vendor LOW (3.3) is *accurate*. CVSS vector AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L says exactly what this is: local attacker, low privileges, availability-only impact. There is no memory corruption, no code execution, no information disclosure. Any user who can hand a file to GPAC can already crash their own GPAC process — and that's the entire blast radius.
3 steps from start to impact.
Attacker crafts a zip-bomb ISOBMFF file
zlib, python -c 'import zlib; ...', or a custom MP4Box-aware fuzzer harness like AFL++ on GPAC's parser corpus) the attacker builds an MP4/MOV/3GP container whose embedded compressed metadata blob inflates to many gigabytes from a few kilobytes of input. No published weaponized PoC exists at time of writing beyond the VulDB/GHSA reproducer.- Knowledge of GPAC's ISOBMFF compressed-meta layout
- A zlib compressor
- No turnkey exploit kit; defenders aren't seeing this in the wild
Attacker delivers the file to a GPAC user or pipeline
MP4Box -info evil.mp4, a transcoding job picking it up from an upload queue, or a CI step that exercises libgpac. There is no network listener; GPAC must be invoked on the file.- Victim runs GPAC on attacker-controlled input
- Pipeline accepts untrusted media uploads
- Most enterprises do not run GPAC server-side
- Upload pipelines that use ffmpeg/HandBrake/Bento4 are unaffected
- Sandboxed transcoders (Docker, gVisor, Lambda) confine the blast
Inflation runs unbounded, process is killed
base_encoding.c calls inflate without comparing output length to input length. Memory balloons until cgroup limit, OOM killer, or process address space ceiling stops it. The GPAC process dies; the parent (shell, transcoder, CI runner) continues. There is no spillover to other tenants or processes that share the host beyond the resource transient.- No cgroup/ulimit memory cap, or a cap larger than available RAM
- Most production transcoders already run under strict memory limits
- OOM kill is bounded — host stays up
dmesg, container exit code 137, exporter job-failure metrics.The supporting signals.
| In-the-wild exploitation | None observed. No KEV listing, no vendor IOCs, no incident reports. |
|---|---|
| Public PoC | Reproducer referenced in VulDB / GHSA-c4wq-769x-vwcv triage; no weaponized public exploit. |
| EPSS | 0.00112 (~0.1%) — bottom-percentile probability of exploitation in the next 30 days. |
| KEV status | Not listed. |
| CVSS v3.1 | AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L — Local, Low priv, Availability-only. Translation: a logged-in user can crash their own GPAC. |
| Affected versions | GPAC ≤ 26.02.0, all platforms (Linux/Windows/macOS). |
| Fixed in | Upstream commit 297f2d8d1f493d8b241330533cd47f7da758aeb3 (32× inflation ratio cap). Distro backports: watch Debian/Ubuntu/Fedora gpac package updates over the next 2–4 weeks. |
| Exposure population | GPAC is not a network service — Shodan/Censys/GreyNoise N/A. Internet-exposed GPAC instances are effectively zero. |
| Disclosure | Published 2026-06-29 via VulDB. |
| Reporter | VulDB community submission; CWE-404 (Improper Resource Shutdown / Release — used here for resource exhaustion). |
noisgate verdict.
Local-only attack vector with availability-only impact in a desktop/CLI media library — the single decisive factor is that exploitation requires the attacker to already have a way to hand a file to a GPAC process they don't own, and the outcome is just crashing that process. Blast radius does not exit the calling process; there is no canonical high-value-role deployment of GPAC where this chain escalates.
Why this verdict
- Local + Low-privilege + Availability-only: CVSS vector tells the whole story. No code execution, no memory corruption, no information leak — just a process crash.
- Friction audit: attacker must already have a way to invoke GPAC on their file. That assumes either a local logged-in user (in which case they're DoS'ing themselves) or a media-processing pipeline that accepts untrusted uploads (a tiny fraction of enterprises, and those typically use ffmpeg).
- Role multiplier: enumerating GPAC's deployment roles — (a) analyst workstation / desktop transcoder = self-DoS, no escalation; (b) backend transcoding service = single job crash, retried by the queue, recovered by cgroup OOM kill; (c) high-value role = *none exist* — GPAC is not an identity provider, hypervisor, EDR agent, CA, backup server, CI runner, or edge appliance. The role-multiplier floor is LOW.
- EPSS 0.00112 + no KEV + no public weaponization: all three exploitation-likelihood signals agree — this stays in the noise floor.
- Compensating controls already standard: any modern container/serverless transcoder runs under memory limits that turn this from outage into job retry.
Why not higher?
MEDIUM would require either network reachability or impact beyond a single process. Neither is present. The CVSS subscore is even slightly inflated because the typical real-world outcome is a retried job, not a sustained service outage.
Why not lower?
IGNORE is wrong because there is a real fix and a real (if narrow) attack — anyone running GPAC server-side against untrusted uploads should still patch on the normal hygiene cycle. LOW correctly says 'backlog, not page'.
What to do — in priority order.
- Run GPAC under strict memory/CPU limits — If GPAC is invoked in a service context, wrap it with
systemd-run --property=MemoryMax=2G --property=CPUQuota=200%or a Docker--memoryflag. This converts the bug from sustained host degradation into a single failed job. No mitigation SLA for LOW — apply opportunistically. - Reject suspicious media before invocation — Pre-screen uploads with
ffprobesize/header sanity checks and a max-file-size gate at the upload layer. Useful baseline hygiene against the broader class of media-parser bugs (GPAC, ffmpeg, ImageMagick), not just this CVE. - Track distro
gpacpackage updates — Subscribe Debian/Ubuntu/RHEL security trackers and let the regular monthly patch cycle pick this up. Apply within the 365-day remediation window. - Audit who actually runs GPAC — Most orgs find GPAC only on a handful of analyst workstations or a single transcoding box. Inventory first — you may be patching three hosts, not ten thousand.
- Network-layer controls (WAF, IDS, firewall rules): the vuln has no network attack surface; perimeter controls are irrelevant.
- EDR behavior rules: the malicious activity is
inflate()doing exactly what it's told. No process-injection, no LOLBin, nothing to alert on beyond an OOM kill. - Disabling compressed metadata in ISOBMFF: there is no runtime toggle in GPAC for this; the only fix is the upstream patch.
Crowdsourced verification payload.
Run on each Linux host that may have GPAC installed (e.g. ./check_gpac.sh on the target). Needs read access to the GPAC binary on PATH; no root required. Outputs VULNERABLE, PATCHED, or UNKNOWN with exit code 1/0/2 respectively.
#!/usr/bin/env bash
# noisgate verification — CVE-2026-13523 (GPAC zlib inflation DoS)
# Compares installed GPAC version against fixed cutoff (>26.02.0 or backported).
set -u
FIXED_AFTER="26.02.0"
if ! command -v MP4Box >/dev/null 2>&1 && ! command -v gpac >/dev/null 2>&1; then
echo "UNKNOWN: GPAC not installed on this host"
exit 2
fi
BIN=$(command -v MP4Box || command -v gpac)
RAW=$("$BIN" -version 2>&1 | head -n 5)
VER=$(echo "$RAW" | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -n1)
if [ -z "$VER" ]; then
echo "UNKNOWN: could not parse GPAC version from: $RAW"
exit 2
fi
# Distro backport check: look for the fix commit short hash in --help/--version output if vendor stamps it
if echo "$RAW" | grep -qiE '297f2d8|CVE-2026-13523'; then
echo "PATCHED: $BIN $VER (backport marker present)"
exit 0
fi
# Pure version comparison
ver_le() { [ "$1" = "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" ]; }
if ver_le "$VER" "$FIXED_AFTER"; then
echo "VULNERABLE: $BIN $VER (<= $FIXED_AFTER, no backport marker found)"
exit 1
else
echo "PATCHED: $BIN $VER (> $FIXED_AFTER)"
exit 0
fi
If you remember one thing.
gpac >26.02.0 or backports commit 297f2d8. If you run GPAC server-side against untrusted uploads (rare — most orgs use ffmpeg), wrap the invocation in a memory-capped container today as a one-time hygiene step. Inventory first; you probably have <10 affected hosts.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.