CVE-2026-54569 IBM QRadar · QRadar

Detect senaite.core Eval Injection and Missing Authorization Exploitation (CVE-2026-54569) in IBM QRadar

Detects exploitation of CVE-2026-54569, a critical (CVSS 9.8) eval injection (CWE-95) and missing authorization (CWE-862) vulnerability in senaite.core versions >= 2.0.0 through <= 2.6.0. senaite.core is a Python/Plone-based Laboratory Information Management System (LIMS). The flaw allows unauthenticated or under-privileged attackers to reach endpoints that pass attacker-controlled input into Python eval()/expression evaluation, enabling remote code execution in the context of the Zope/Plone application server. Detection focuses on suspicious HTTP requests to senaite endpoints containing Python expression payloads (e.g. __import__, os.system, subprocess) and on anomalous child processes spawned by the Zope/senaite Python process, which is the primary post-exploitation signal.

MITRE ATT&CK

Tactic
Initial Access Execution

QRadar Detection Query

IBM QRadar (QRadar)
sql
SELECT sourceip, destinationip, "URL", "userAgent", QIDNAME(qid) AS event, starttime FROM events WHERE ("URL" ILIKE '%/senaite%' OR "URL" ILIKE '%/@@%' OR "URL" ILIKE '%/bika_setup%' OR "URL" ILIKE '%/portal_setup%') AND ("URL" ILIKE '%__import__%' OR "URL" ILIKE '%os.system%' OR "URL" ILIKE '%subprocess%' OR "URL" ILIKE '%eval(%' OR "URL" ILIKE '%exec(%' OR "URL" ILIKE '%popen%') ORDER BY starttime DESC LAST 24 HOURS
critical severity medium confidence

QRadar AQL to surface web events targeting senaite endpoints with Python eval-injection markers in the URL.

Data Sources

Web Server LogsProxyWAF

Required Tables

events

False Positives & Tuning

  • Legitimate Plone TTW expression editing by senaite administrators
  • Authorized scanning or penetration testing
  • Benign automation referencing Python module names in URLs

Other platforms for CVE-2026-54569


Testing Methodology

Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Simulated eval-injection probe against senaite endpoint

    Expected signal: Web server access log entry to a /senaite endpoint whose query contains __import__ and os.system.

  2. Test 2Suspicious child process from Zope/python server

    Expected signal: ProcessRollup2/process-start event with ParentBaseFileName python3 spawning /bin/sh.

  3. Test 3Missing-authorization access to protected senaite endpoint

    Expected signal: Web access log entry to a privileged senaite management path from an unauthenticated source.


Response Playbook

Triage

  1. Confirm the target host runs senaite.core and identify its version; versions >= 2.0.0 through <= 2.6.0 are vulnerable to CVE-2026-54569.
  2. Extract the full decoded URL/query and request body from the flagged web request and confirm whether it contains a valid Python expression payload (e.g. __import__, os.system, subprocess) rather than a benign string.
  3. Correlate the source IP against threat intelligence and check whether the same IP made prior reconnaissance requests or hit missing-authorization endpoints without credentials.
  4. Review the HTTP response status code — a 200 with an unusual body size may indicate successful code execution versus a 4xx/5xx indicating a blocked attempt.

Containment

  1. Block the offending source IP(s) at the WAF/perimeter and rate-limit or restrict access to the senaite management and expression-evaluation endpoints.
  2. If active exploitation is confirmed, isolate the senaite/Zope application server from the network to prevent lateral movement and data exfiltration of lab records.
  3. Apply the vendor fix by upgrading senaite.core beyond 2.6.0 (per PRs #2903 and #2919) or apply the patch commits, then restart the Zope instance.

Evidence Collection

  1. Preserve web server access logs (IIS/nginx/Apache) and Zope event/access logs covering the request window, including full URLs and request bodies.
  2. Capture the process tree and command lines of any child processes spawned by the python/zope process, along with EDR process telemetry and memory if RCE is suspected.
  3. Snapshot the senaite/Plone datastore (Data.fs) and any files written to disk in the app directory or /tmp during the incident window.

Escalation Criteria

  • !Escalate to incident response immediately if a suspicious child process (shell, curl, wget, nc, python) was spawned by the Zope/python server following the injection request.
  • !Escalate if the flagged request returned HTTP 200 and was followed by outbound connections to unknown external hosts, indicating successful RCE and possible C2.
  • !Escalate if lab result/patient data access or exfiltration is observed, given senaite is a LIMS handling sensitive laboratory records.

Investigation Guide

Related Techniques

Forensic Artifacts

  • >Web server access logs showing requests to senaite endpoints with Python expression payloads.
  • >Zope event.log / access.log entries and any Python tracebacks around the request time.
  • >Child process command lines and files created by the python/zope process (e.g. dropped scripts in /tmp or the instance directory).

Tuning Guidance

Baseline legitimate administrator use of the Plone through-the-web (TTW) TAL/Python expression editor, which can legitimately contain expression-like syntax, and exclude known admin source IPs and authenticated admin sessions. Restrict the query to internet-facing senaite hosts, and where possible require the missing-authorization signal (no valid session/credential) to fire alongside the payload marker to reduce false positives. Add authorized scanner IP ranges to an allowlist.


Hunting Queries

Hunt for repeated eval-injection probing against senaite endpoints across the environment.

Hunting — KQL
kql
W3CIISLog | extend d = url_decode(csUriQuery) | where d has_any("__import__","os.system","subprocess","eval(") | summarize count() by cIP, csUriStem, bin(TimeGenerated, 1h)
Hunting — SPL
spl
index=web (senaite OR bika_setup) | eval d=urldecode(uri_query) | where match(d,"(?i)(__import__|os\.system|subprocess|eval\()") | stats count by src_ip, uri_path

Atomic Red Team Tests

Test 1 Simulated eval-injection probe against senaite endpoint
linux

Sends an HTTP request to a lab senaite instance with a Python expression payload in the query string to validate web-log detection.

Command

bash
curl -s -o /dev/null -w '%{http_code}' "http://senaite-lab.local:8080/senaite/@@evaluate?expr=__import__('os').system('id')"

Cleanup

bash
rm -f /tmp/senaite_probe.log

Expected Telemetry

Web server access log entry to a /senaite endpoint whose query contains __import__ and os.system.

Expected Detection

The kql/spl web-log queries flag the request as an eval-injection probe.

Test 2 Suspicious child process from Zope/python server
linux

Simulates post-exploitation by having a python parent spawn a shell command, mimicking RCE via the eval injection.

Command

bash
python3 -c "import subprocess; subprocess.call(['/bin/sh','-c','id; hostname'])"

Cleanup

bash
true

Expected Telemetry

ProcessRollup2/process-start event with ParentBaseFileName python3 spawning /bin/sh.

Expected Detection

The crowdstrike_cql and elastic_eql process/sequence queries detect the anomalous child process.

Test 3 Missing-authorization access to protected senaite endpoint
linux

Sends an unauthenticated request to a senaite endpoint that should require authorization, validating detection of the CWE-862 component.

Command

bash
curl -s -o /dev/null -w '%{http_code}' "http://senaite-lab.local:8080/senaite/bika_setup/manage_main"

Cleanup

bash
true

Expected Telemetry

Web access log entry to a privileged senaite management path from an unauthenticated source.

Expected Detection

Web-log queries surface unauthenticated access to protected senaite management endpoints.

Related Detections