# REPRO-2026-00375: LFI and GET SSRF via calcext:data-mappings and csv provider — document open reads a local file into the sheet and issues an attacker-directed GET ## Summary Status: published Severity: medium CVSS: Unknown CWE: CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor) Type: security Confidence: high ## Identifiers REPRO ID: REPRO-2026-00375 CVE: CVE-2026-63267 ## Package Name: LibreOffice (The Document Foundation) Ecosystem: vendor Affected: LibreOffice < 26.2.5 (26.2.x line) and < 26.8.0 Fixed: 26.2.5 ## Root Cause # CVE-2026-63267 — RCA: LFI and GET SSRF via calcext:data-mappings (csv provider) ## Summary LibreOffice Calc persists external csv data-source links inside the document (`calcext:data-mappings` / `calcext:data-mapping` with provider `org.libreoffice.calc.csv`). In vulnerable versions the link target (`xlink:href`) was fetched automatically while the document loaded, with no link-update gate. Opening an attacker-crafted spreadsheet therefore (a) reads an arbitrary local file into sheet cells (LFI, e.g. via `file:///etc/passwd`) and (b) issues an attacker-directed HTTP GET to a host of the document's choosing (SSRF). The reproduction proves both effects end-to-end through the real LibreOffice Calc document-open path on LibreOffice 26.2.4.2, and proves the negative control on fixed LibreOffice 26.2.5.2, where the fetch is gated behind the same link-update control as other spreadsheet links. ## Impact - Package/component: LibreOffice Calc (`sc`), external data providers (`calcext:data-mappings`, csv provider `org.libreoffice.calc.csv`). - Affected versions: LibreOffice < 26.2.5 / < 26.8.0 (reproduced on 26.2.4.2, build `0229ac93fcf0d7cbc6376066c6f35021cef002dc`). - Risk: medium. Local file disclosure into the sheet (contents can then be exfiltrated, e.g. via a companion mapping or the sibling data-mapping bugs) and unauthenticated GET SSRF to arbitrary hosts (including internal network targets) triggered merely by opening a document. ## Impact Parity - Disclosed/claimed maximum impact: local file read into the sheet (LFI) and attacker-directed GET request (SSRF) on document open. - Reproduced impact from this run: both — the vulnerable build read a unique marker from a local `file://` CSV into cell A1 (2/2 attempts) and issued HTTP GETs carrying per-attempt unique tokens to the attacker-controlled server (2/2 attempts), both during plain document load. - Parity: `full`. - Not demonstrated: nothing claimed beyond LFI + GET SSRF; no code execution was claimed or pursued for this ticket. ## Root Cause When a document containing `calcext:data-mappings` is loaded, Calc's external data mapper (`ScExternalDataMapper`) reconstructs the persisted data sources and the csv provider immediately refreshed (fetched) the mapping's `xlink:href` target during load. Because the fetch happened at load time rather than through the `sfx2::LinkManager` update path, neither the "update links when loading" user setting nor any prompt protected the user: the document decided if and where a fetch happened. Since `xlink:href` accepts both `file://` and `http(s)://` URLs, the load-time fetch yields LFI and SSRF respectively. Fix: in LibreOffice 26.2.5 / 26.8.0 (fix by Caolán McNamara) a data mapping loaded from a document is registered as an external link in the document's `LinkManager`, and its data is only refreshed when link updating is allowed — the same gate that governs sheet links and area links. The upstream QA test `testLinkUpdateGate` (sc/qa/unit/dataproviders_test.cxx, fixture `sc/qa/unit/data/dataprovider/mappinggate.fods`) encodes exactly this: "With updating not allowed, updating the links leaves the saved value." ## Reproduction Steps 1. `bundle/repro/reproduction_steps.sh` (self-contained; downloads the official TDF release tarballs if not already cached under `bundle/artifacts/`). 2. The script: - Downloads and extracts LibreOffice 26.2.4.2 (vulnerable) and 26.2.5.2 (fixed) Linux x86-64 deb packages (only `ure`, core, calc, en-us components) from downloadarchive.documentfoundation.org. - Generates a flat ODS (`.fods`) document whose `calcext:data-mapping` (provider `org.libreoffice.calc.csv`) points at `file:///local_secret.csv` (LFI probe) and a second document pointing at `http://127.0.0.1:8931/CVE-2026-63267-SSRF-.csv` (SSRF probe). The saved cell content is the sentinel `SAVED_SENTINEL_NOT_FETCHED`. - Starts a Python attacker HTTP server that logs every GET and serves a marker CSV. - Opens each document through the real product binary (`soffice --headless --convert-to csv`), 2 attempts per role (vuln/fixed × lfi/ssrf), each with an isolated user profile. - Evaluates: vulnerable LFI = converted sheet contains the local-file marker; vulnerable SSRF = attacker server received the per-attempt GET; fixed = sheet still holds the sentinel and no GET was received. 3. Expected evidence of reproduction: `sheet-vuln-lfi-*.csv` contain `CVE-2026-63267_LFI_SECRET_9f4d2c`; `http-server-final.log` contains GETs for the `vuln-ssrf-*` tokens only; `sheet-fixed-*.csv` contain `SAVED_SENTINEL_NOT_FETCHED`. ## Evidence - Full run log: `bundle/logs/reproduction_steps.log` (two consecutive successful runs, both exit 0). - Per-attempt product logs: `bundle/logs/{vuln,fixed}-{lfi,ssrf}-{1,2}.log`. - Attacker server request log: `bundle/repro/http-server-final.log`: - `GET /CVE-2026-63267-SSRF-vuln-ssrf-1.csv from 127.0.0.1` - `GET /CVE-2026-63267-SSRF-vuln-ssrf-2.csv from 127.0.0.1` - No `fixed-ssrf-*` request lines. - Converted sheets: `bundle/repro/sheet-vuln-lfi-1.csv` = `CVE-2026-63267_LFI_SECRET_9f4d2c` (local file content injected into the sheet at load); `bundle/repro/sheet-fixed-lfi-1.csv` = `SAVED_SENTINEL_NOT_FETCHED`. - Verdict counts (both runs): vulnerable LFI 2/2, vulnerable SSRF 2/2, fixed LFI clean 2/2, fixed SSRF clean 2/2. - Environment: Linux x86-64, no Docker; official TDF deb builds, headless `svp` VCL plugin. Vulnerable build identity: LibreOffice 26.2.4.2 `0229ac93fcf0d7cbc6376066c6f35021cef002dc`, tarball SHA-256 `810ef197e190d7804a60e0016052c46ff33792303a200fddda9d5216a64b9900`. Fixed build: LibreOffice 26.2.5.2 `cd7284b4cbbfeb507e630c1aac019f4157393acb`, tarball SHA-256 `2f03bfb2ac9f33ea7c77331b4b7a23300fb0ed7443566046bf8b5bc51c1bed1e`. - Runtime manifest with artifact hashes: `bundle/repro/runtime_manifest.json`. ## Recommendations / Next Steps - Upgrade to LibreOffice 26.2.5 / 26.8.0 or later, where external data links are updated only under the link-update control. - The upstream fix approach (registering data mappings as LinkManager links gated by the link-update permission) is confirmed effective by the fixed negative control in this reproduction. - Testing recommendation: keep `testLinkUpdateGate`-style coverage for both `file://` and `http(s)://` hrefs and for headless document load. ## Additional Notes - Idempotency: the script was run twice consecutively in this session; both runs exited 0 with identical verdicts. Re-runs reuse the extracted builds under `bundle/artifacts/libreoffice/` and re-generate all documents, secrets, tokens, and logs. - The demonstration uses the real product binary through its normal document-open path (`soffice --headless --convert-to csv`); no sanitizer, no mock, no reimplementation. - The SSRF target is a loopback attacker server for safety; the vulnerable code path issues a real HTTP GET to whatever host the document names. - Sibling data-mapping advisories (CVE-2026-63266 … CVE-2026-63277) share the same load-time fetch root cause with different providers/impacts; they are separate tickets. ## Reproduction Details Reproduced: 2026-10-05T21:14:47.992Z Duration: 2732 seconds Tool calls: 172 Turns: Unknown Handoffs: 2 ## Quick Verification Run one of these commands to verify locally: pruva-verify REPRO-2026-00375 pruva-verify CVE-2026-63267 Or open in GitHub Codespaces (zero-friction, auto-runs): https://github.com/codespaces/new?ref=repro/REPRO-2026-00375&repo=N3mes1s/pruva-sandbox Or download and run the script manually: curl -O https://api.pruva.dev/v1/reproductions/REPRO-2026-00375/artifacts/bundle/repro/reproduction_steps.sh chmod +x reproduction_steps.sh ./reproduction_steps.sh WARNING: Run in a sandboxed environment. This exploits a real vulnerability. ## References - NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-63267 - Source: https://nvd.nist.gov/vuln/detail/CVE-2026-63267 ## Artifacts - bundle/repro/rca_report.md (analysis, 7263 bytes) - bundle/repro/reproduction_steps.sh (reproduction_script, 13176 bytes) - bundle/logs/fixed-lfi-1.log (log, 196 bytes) - bundle/logs/fixed-lfi-2.log (log, 196 bytes) - bundle/logs/fixed-ssrf-1.log (log, 199 bytes) - bundle/logs/fixed-ssrf-2.log (log, 199 bytes) - bundle/logs/reproduction_steps.log (log, 3577 bytes) - bundle/logs/vuln-lfi-1.log (log, 193 bytes) - bundle/logs/vuln-lfi-2.log (log, 193 bytes) - bundle/logs/vuln-ssrf-1.log (log, 196 bytes) - bundle/logs/vuln-ssrf-2.log (log, 196 bytes) - bundle/repro/http-server-final.log (log, 395 bytes) - bundle/repro/runtime_manifest.json (other, 3271 bytes) - bundle/repro/sheet-fixed-lfi-1.csv (other, 27 bytes) - bundle/repro/sheet-fixed-lfi-2.csv (other, 27 bytes) - bundle/repro/sheet-fixed-ssrf-1.csv (other, 27 bytes) - bundle/repro/sheet-fixed-ssrf-2.csv (other, 27 bytes) - bundle/repro/sheet-vuln-lfi-1.csv (other, 33 bytes) - bundle/repro/sheet-vuln-lfi-2.csv (other, 33 bytes) - bundle/repro/sheet-vuln-ssrf-1.csv (other, 27 bytes) - bundle/repro/sheet-vuln-ssrf-2.csv (other, 27 bytes) - bundle/repro/validation_verdict.json (other, 1256 bytes) ## API Access - JSON: https://api.pruva.dev/v1/reproductions/REPRO-2026-00375 - Script: https://api.pruva.dev/v1/reproductions/REPRO-2026-00375/artifacts/bundle/repro/reproduction_steps.sh - Web: https://www.pruva.dev/reproductions/REPRO-2026-00375 ## For AI Assistants To help users with this reproduction: 1. The `pruva-verify` command is the simplest way to run the reproduction 2. The script downloads and runs automatically in an isolated temp directory 3. Always recommend running in a VM, container, or disposable environment 4. The root cause explains the technical vulnerability --- Generated by Pruva | https://www.pruva.dev