CVE-2026-63269: Verified Reproduction
CVE-2026-63269: LFI and GET SSRF via GStreamer and HLS playlists — linked media makes GStreamer read local files and fetch remote URLs on open
CVE-2026-63269 is verified against LibreOffice/core · unknown. Affected versions: LibreOffice before 26.2.5 (26.2 line) and before 26.8.0; vulnerable baseline 26.2.4.x. Fixed in 26.2.5. Vulnerability class: SSRF. This medium reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00378.
What Is CVE-2026-63269?
CVE-2026-63269 is a medium-severity SSRF vulnerability affecting LibreOffice/core LibreOffice before 26.2.5 (26.2 line) and before 26.8.0; vulnerable baseline 26.2.4.x. Pruva has independently reproduced it and publishes a verified, runnable proof-of-concept (reproduction REPRO-2026-00378).
CVE-2026-63269 Severity & CVSS Score
CVE-2026-63269 is rated medium severity, with a CVSS base score of 6.7 out of 10.
Medium — meaningful risk under specific conditions. Schedule a fix in the normal cycle.
Affected LibreOffice/core Versions
LibreOffice/core · unknown versions LibreOffice before 26.2.5 (26.2 line) and before 26.8.0; vulnerable baseline 26.2.4.x are affected.
How to Reproduce CVE-2026-63269
pruva-verify REPRO-2026-00378 curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00378/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-63269
- reached the target end-to-end
- full exploit chain demonstrated
- on the real production code path
- high confidence
- the upstream fix blocks the same trigger
Crafted ODP document whose linked media (draw:plugin) URL points to an attacker-hosted HLS playlist listing a local file:// path and a remote http:// URL
- soffice open
- Impress media shape
- avmedia GStreamer playbin
- hlsdemux follows playlist URIs (souphttpsrc GET + filesrc local read)
How the agent worked
Root Cause and Exploit Chain for CVE-2026-63269
LibreOffice documents can contain linked audio/video media objects (ODF
draw:plugin inside a draw:frame, e.g. an Impress MediaShape). On Linux,
LibreOffice plays such media through its avmedia GStreamer backend. In
vulnerable versions, merely opening a document causes LibreOffice to hand
the linked media URL to GStreamer's playbin, which resolves and prerolls the
stream without any user interaction or link-update consent. If the linked
media is an HLS playlist (.m3u8), GStreamer's hlsdemux follows every URI
listed in the playlist — including file:// URIs naming local files and
http(s):// URLs naming arbitrary remote hosts — so a crafted document makes
the victim's machine read local files and issue attacker-directed GET requests
simply by being opened.
- Package/component affected: LibreOffice (avmedia GStreamer backend,
libavmediagst.so; document media shapes in Impress/Draw). - Affected versions: LibreOffice < 26.2.5 / < 26.8.0 (reproduced on the TDF 26.2.4.2 Linux x86-64 deb build).
- Risk level and consequences: Medium (CVSS 6.7 per advisory). Remote,
unauthenticated attacker delivers a document; on open, the victim's
LibreOffice performs:
- LFI: local files named in the playlist are opened and read by
GStreamer (
filesrc), and their contents can end up in the document (per the advisory), enabling file disclosure. - GET SSRF: arbitrary remote URLs listed in the playlist are fetched
from the victim host (here:
GStreamer souphttpsrcHTTP requests), reaching internal/loopback services.
- LFI: local files named in the playlist are opened and read by
GStreamer (
Impact Parity
- Disclosed/claimed maximum impact: LFI + GET SSRF via GStreamer following
a document-linked HLS playlist (
expected_impact=ssrf, surfaceviewer_document, entrypointopen_document). - Reproduced impact from this run: Full LFI + GET SSRF on document open
through the real product (LibreOffice Impress 26.2.4.2 under Xvfb):
the attacker HTTP server received the playlist GET and the SSRF segment GET
from
GStreamer souphttpsrc, andstracecaptured the soffice/GStreamer process tree opening the local secret file referenced by afile://playlist entry. Two independent vulnerable attempts reproduced both effects; two fixed-version (26.2.5.2) attempts fetched nothing at all. - Parity:
full - Not demonstrated: exfiltration of the local file's contents back to the attacker (the advisory's "contents could end up in the document" leg); the local read itself and the remote fetch are both proven.
Root Cause
LibreOffice's media shape (SdrMediaObj / avmedia::MediaWindow) creates a
GStreamer playbin for the persisted linked-media URL as soon as the slide
containing the media object is displayed — which happens during document load
for the first page — and sets it to the paused/preroll state to render a
preview frame. Prerolling an HLS playlist makes hlsdemux download the
manifest and then fetch every fragment URI it lists. Neither LibreOffice nor
GStreamer restricted:
- the scheme of fragment URIs inside a playlist served over HTTP
(
file://entries are honored byfilesrc), or - the remote URLs a playlist can direct the player to (any
http(s)://target is fetched bysouphttpsrc).
Additionally, linked media was loaded automatically on document open without being subject to LibreOffice's link-update consent.
Fix (LibreOffice 26.2.5 / 26.8.0, by Caolán McNamara): per the advisory, "LibreOffice does not follow playlists that name further resources, and linked media is under link update control." In this run's negative control, the fixed 26.2.5.2 build did not even fetch the playlist when opening the same crafted document (linked media now requires link-update consent, suppressed in an unattended open), and a fortiori never followed playlist-listed resources.
Reproduction Steps
bundle/repro/reproduction_steps.sh(self-contained; safe to re-run).- What it does:
- Installs runtime deps (
xvfb,strace, GStreamer good/bad/libav plugins) and downloads/extracts the official TDF deb builds LibreOffice 26.2.4.2 (vulnerable) and 26.2.5.2 (fixed) into the prepared project cache. - Generates a valid MPEG-TS fragment (so playback genuinely proceeds through the playlist instead of erroring on undecodable bytes).
- For each attempt (2 vulnerable + 2 fixed), it:
- starts a local "attacker" HTTP server (python3) that logs every
request and serves
/stream.m3u8; - writes an HLS playlist listing one remote URL
(
http://127.0.0.1:PORT/ssrf-segment-<tag>-<n>.ts— the SSRF probe) and one local file (file://.../lfi-secret.txt— the LFI probe); - generates a crafted ODP whose slide 1 contains a linked media object
(
draw:pluginwithdraw:mime-type="application/vnd.sun.star.media") pointing at the playlist; - opens the document with the real
sofficeunder Xvfb, tracingopenat()withstrace -f; - records playlist GETs, segment GETs, and local-file opens.
- starts a local "attacker" HTTP server (python3) that logs every
request and serves
- Installs runtime deps (
- Expected evidence of reproduction:
- Vulnerable attempts:
http.logshowsGET /stream.m3u8andGET /ssrf-segment-...with User-AgentGStreamer souphttpsrc;lfi-evidence.txtshowsopenat(... "lfi-secret.txt" ...) = <fd>. - Fixed attempts: neither the playlist nor the segment is fetched and the secret file is never opened.
- Vulnerable attempts:
Evidence
- Full run log:
bundle/logs/reproduction_steps.log(run 1) andbundle/logs/reproduction_steps_run2.log(run 2). - Per-attempt proof under
bundle/repro/proof/<tag>-<n>/:http.log— attacker-server request log, e.g. vulnerable-2:GET /stream.m3u8 ua=GStreamer souphttpsrc 1.28.2 libsoup/3.6.6followed byGET /ssrf-segment-vulnerable-2.ts(same UA).lfi-evidence.txt— strace excerpt, e.g. vulnerable-1:openat(AT_FDCWD, ".../proof/vulnerable-1/lfi-secret.txt", O_RDONLY) = 40.stream.m3u8— the exact playlist served;soffice.log— product stderr.
- Machine-readable manifest with artifact hashes:
bundle/repro/runtime_manifest.json. - Verdict:
bundle/repro/validation_verdict.json. - Environment: Ubuntu 26.04 x86_64, LibreOffice 26.2.4.2 TDF deb (tarball
sha256
810ef197…4b9900) vs LibreOffice 26.2.5.2 TDF deb (tarball sha2562f03bfb2…1bed1e), GStreamer 1.28.2, Xvfb display, no sanitizers — real product binaries exercised through the real document-open path.
Recommendations / Next Steps
- Upgrade to LibreOffice ≥ 26.2.5 / ≥ 26.8.0 (fixed).
- The fix approach per the advisory: do not follow playlists that name further resources in the media backend, and put linked media behind link-update consent.
- Testing: open a document with a linked-media HLS playlist referencing
file://and remote URLs; assert no outbound requests and no local file opens occur without explicit link-update consent.
Additional Notes
- Idempotency: the script was run twice consecutively; both runs produced the confirmed verdict (2/2 vulnerable attempts positive, 2/2 fixed attempts negative each run). Downloads/extractions are cached in the prepared project cache and reused across runs; proof directories are regenerated per run.
- Document format detail: the ODF media link must use
draw:mime-type="application/vnd.sun.star.media"; using an HLS-specific MIME type makes the ODF importer drop the URL (verified by round-tripping through the vulnerable build itself). The structure was derived from a reference document created programmatically via UNO (com.sun.star.drawing.MediaShape.MediaURL). - Limitations: content exfiltration of the read file into the saved document was not needed to prove the claim ("local file reads and remote fetches") and was not attempted; the read and fetch primitives are demonstrated directly.
CVE-2026-63269 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
set -x; id; uname -a; command -v libreoffice soffice strace Xvfb python3 docker gst-launch-1.0 2>/dev/null; ls /pruva/project-cache/ 2>/dev/null; cat /pruva/project-cache/.pruva/cache_manifest.json 2>/dev/null; docker ps 2>&1 | head -3; df -h /workspace /tmp /pruva 2>/dev/null | head; cat /etc/os-release | head -3uid=1000(vscode) gid=1000(vscode) groups=1000(vscode)
Linux a184082c97a2 6.8.0-142-generic #142-Ubuntu SMP PREEMPT_DYNAMIC Wed Sep 2 14:24:27 UTC 2026 x86_64 GNU/Linux
repo-mirrors
{
"schema_version": 1,
"entries": [
{
"path": "repo-mirrors",curl -fsSL 'https://downloadarchive.documentfoundation.org/libreoffice/old/' | grep -oE 'href="26\.[0-9.]+/"' | sort -u | tail -20href="26.2.0.1/" href="26.2.0.2/" href="26.2.0.3/" href="26.2.1.1/" href="26.2.1.2/" href="26.2.2.1/" href="26.2.2.2/" href="26.2.3.1/"
ls -la /pruva/project-cache/repo-mirrors/ 2>/dev/null; for d in /pruva/project-cache/repo-mirrors/*/; do echo "== $d"; git -C "$d" remote -v 2>/dev/null | head -2; donetotal 0 drwx------ 2 vscode vscode 40 Oct 5 20:41 . drwx------ 4 vscode vscode 80 Oct 5 20:41 .. == /pruva/project-cache/repo-mirrors/*/
Artifacts and Evidence for CVE-2026-63269
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2026-63269
Upgrade LibreOffice/core · unknown to 26.2.5 or later.
FAQ: CVE-2026-63269
Is CVE-2026-63269 exploitable?
How severe is CVE-2026-63269?
What type of vulnerability is CVE-2026-63269?
Which versions of LibreOffice/core are affected by CVE-2026-63269?
Is there a fix for CVE-2026-63269?
How can I reproduce CVE-2026-63269?
Is the CVE-2026-63269 reproduction verified?
References for CVE-2026-63269
Authoritative sources for CVE-2026-63269 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.