Sep 25, 2026·5 min read·16 visits
An incomplete security fix in compliance-trestle allows path traversal, arbitrary file write, and recursive directory deletion across multiple subcommands by manipulating the output path parameter.
CVE-2026-57171 describes an incomplete fix of CVE-2026-46345 inside compliance-trestle. Sibling subcommands (catalog-generate, profile-generate, ssp-generate, create, and replicate) bypass path validation routines. An attacker can manipulate output parameters to perform arbitrary file writes and directory deletions.
The Python-based Software Development Kit (SDK) and command-line tool compliance-trestle (Trestle) facilitates the management of Open Security Controls Assessment Language (OSCAL) documents. Trestle relies on structured workspace directories to catalog, profile, and track system security plans. While these operations typically target local repository files, the application-level directory boundaries are frequently used as security boundaries within automated pipelines.
During the remediation of a prior path traversal vulnerability (CVE-2026-46345), engineers introduced validation constraints targeting the jinja subcommand. This specific mitigation validated generated outputs through the PathSecurityValidator.validate_local_path() method. However, this defensive check was not systematically applied across sibling commands that share equivalent output mechanisms.
Consequently, several core command-line modules remained vulnerable to input-controlled path traversal. An attacker capable of defining output arguments can direct the execution environment to write files outside the designated workspace. This configuration also allows directory destruction depending on associated flags.
The vulnerability stems from the incomplete implementation of directory validation checks within sibling commands. Commands such as catalog-generate, profile-generate, ssp-generate, create, and replicate historically bypassed the PathSecurityValidator. Instead, they evaluated user-supplied path inputs via is_directory_name_allowed() which was designed to prevent name collision with core OSCAL directories.
This validation check contained two logical flaws. First, if a path starts with a Unix root separator, pathlib.Path(name).parts[0] resolves to the root directory itself. Because the root directory does not exist in the defined restricted directories, the method returns a truthy validation success. Second, path relative traversals (such as subdir/../../) resolve the first element of parts as subdir, which also successfully passes the constraint checks.
Once authorized, the path joining logic invokes Python's standard pathlib division operator. If the configured path argument is absolute, Python discards the preceding workspace root variable entirely. If the input contains relative directory traversals, the resolved output directory escapes the workspace bounds. Additionally, when a user specifies the --force-overwrite option, the program calls clear_folder(), which recursively deletes the target path before writing files.
The vulnerable code in trestle/common/file_utils.py checked output folders using basic slicing of uncanonicalized path components. It failed to check for absolute paths or relative dot-dot sequences.
# Vulnerable Implementation
def is_directory_name_allowed(name: str) -> bool:
pathed_name = pathlib.Path(name)
root_path = pathed_name.parts[0]
if root_path in const.MODEL_TYPE_TO_MODEL_DIR.values():
logger.warning('Task name is the same as an OSCAL schema name.')
return FalseThe patch addresses this gap by introducing explicit validation checks for both absolute paths and the presence of .. segments inside the file_utils.py validation logic. It also updates the vulnerable command files to call PathSecurityValidator.validate_local_path immediately after constructing the output path.
# Patched Implementation in trestle/common/file_utils.py
def is_directory_name_allowed(name: str) -> bool:
pathed_name = pathlib.Path(name)
# Reject absolute paths explicitly
if pathed_name.is_absolute() or name.startswith('/'):
logger.warning('Task name must not be an absolute path')
return False
# Reject traversal sequences
if '..' in pathed_name.parts:
logger.warning('Task name must not contain ".." path traversal sequences')
return False
root_path = pathed_name.parts[0]
if root_path in const.MODEL_TYPE_TO_MODEL_DIR.values():
logger.warning('Task name is the same as an OSCAL schema name.')
return FalseAdditionally, all affected CLI subcommands (e.g., trestle/core/commands/author/catalog.py) were patched to enforce path boundaries:
# Added check in affected commands
markdown_path = trestle_root / args.output
PathSecurityValidator.validate_local_path(markdown_path, trestle_root)Exploitation requires an execution context where the output file path parameter (-o or --output) is influenced by an untrusted source. This scenario is common in shared, multi-tenant build environments, CI/CD pipelines, or automation scripts that parse user-provided metadata or pull request properties.
An attacker can structure an exploit payload using standard relative path sequences or absolute system paths. When the Trestle utility parses the input argument, it performs the directory validation steps on the uncanonicalized input. The command then executes, leading to directory deletion (if forced) and file placement outside the workspace.
This path-resolution mechanism permits an attacker to targeting sensitive directories on the execution runner, such as /etc/cron.d or /var/www. If the execution runner possesses high privileges, this can lead to system-wide compromise or denial of service.
The impact of CVE-2026-57171 affects system integrity and availability. An attacker can write arbitrary compliance schema files to sensitive operating system paths, potentially overwriting system libraries or configurations.
If the runner process operates with elevated privileges, this primitive enables local privilege escalation. For example, writing arbitrary files to /etc/cron.d or active system service folders allows execution of arbitrary commands. This risk is highly relevant in multi-tenant environments where a single pipeline runs validation workflows on behalf of multiple untrusted repository contributors.
The inclusion of folder clearing logic (clear_folder) also introduces a high-impact availability risk. By pointing the output directory to system-critical paths with force flags active, an attacker can delete directories, resulting in permanent damage to execution environments or build runners.
Remediation requires upgrading the compliance-trestle installation to a safe release version. The patch has been backported to both the 3.x and 4.x branches. Workspaces should transition to 3.12.4 (for v3 deployments) or 4.1.0 (for v4 deployments).
If immediate upgrading is not possible, execution environments must implement input filtering on CLI commands. Ensure that parameters parsed from untrusted inputs are checked for traversal patterns (..) or absolute directories.
Security teams can deploy Semgrep rules to detect instances of unvalidated input patterns in their automation pipelines. Systems can also audit command logs to intercept suspicious traversal patterns targeting Trestle execution targets.
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
compliance-trestle IBM / OSCAL Compass | < 3.12.4 | 3.12.4 |
compliance-trestle IBM / OSCAL Compass | >= 4.0.0, <= 4.0.3 | 4.1.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 |
| Attack Vector | Local |
| CVSS Severity Score | 7.7 |
| EPSS Score | 0.00211 |
| Exploit Status | poc |
| CISA KEV Status | Not Listed |
The software uses external input to construct a pathname that should be within a restricted directory, but it does not properly neutralize sequences such as '..' or absolute paths that can resolve to locations outside of the restricted directory.
CVE-2026-16454 is an object-level authorization bypass vulnerability (CWE-284, CWE-862) in Eclipse hawkBit versions 1.0.3 and prior. The flaw exists within the Direct Device Integration (DDI) REST controller (hawkbit-ddi-resource), where endpoints responsible for enumerating software module metadata and serving firmware binaries fail to verify whether the requested software module is assigned to the authenticated device. Consequently, any device with valid credentials (such as a TargetToken or GatewayToken) can enumerate software module identifiers and download arbitrary firmware artifacts across the entire tenant namespace.
CVE-2026-62284 (GHSA-5w5g-j6hw-6p8f) is a code injection and server-side request forgery vulnerability in the console-proxy component of the OSAC Operator. The RemoteConfigResolver parses Kubernetes Secrets containing kubeconfig files via clientcmd.RESTConfigFromKubeConfig without sanitizing execution-related fields. An attacker with RBAC permissions to create or modify labeled Secrets in monitored namespaces can supply a malicious exec credential plugin, resulting in arbitrary command execution within the console-proxy pod.
CVE-2026-62361 (GHSA-xgjr-7j9q-2h4r) is an authenticated SQL injection and authorization bypass vulnerability in listmonk, an open-source, self-hosted newsletter and mailing list manager written in Go. In versions prior to 6.2.0, the subscriber export endpoint (GET /api/subscribers/export) directly interpolates user-supplied SQL filter expressions into a PostgreSQL query without invoking the table allowlist validation function (validateQueryTables). Consequently, authenticated users possessing the subscribers:sql_query and subscribers:get_all permissions can bypass relational access controls, execute arbitrary subqueries against restricted tables such as users and settings, and modify database state via writable Common Table Expressions (CTEs).
CVE-2026-28385 (GHSA-3gq2-x4qg-p4g6) is a Server-Side Request Forgery (SSRF) vulnerability in Canonical LXD versions 4.12 through 6.9. An authenticated user possessing the can_create_images entitlement can force the LXD daemon to execute arbitrary outbound HTTP and HTTPS requests via the /1.0/images API endpoint. Due to the absence of egress destination validation, an attacker can probe host loopback services, RFC 1918 private network segments, and cloud Instance Metadata Services (IMDS) from the network position of the privileged LXD daemon.
Canonical LXD and LXC Incus contain an arbitrary file write vulnerability (CWE-73 / CWE-59) in the `/1.0/instances/<name>/exec` REST API endpoint. When an instance is unpacked from an image archive, top-level symbolic links are extracted directly onto the host filesystem within the instance storage directory. If a crafted image includes a symbolic link named `exec-output` pointing to an arbitrary host path, invoking the execution endpoint with `record-output: true` causes the privileged host daemon to follow the symlink and write command output files directly to the target host directory. An authenticated attacker with permissions to import images and execute commands can exploit this flaw to write controlled content to sensitive host directories such as `/etc/cron.d`, resulting in arbitrary code execution on the host as `root`.
CVE-2026-48749 (tracked as GHSA-vghh-5rfx-xhq8 for LXD and GHSA-2q3f-q5pq-g8wv for Incus) is a critical container escape vulnerability in the Canonical LXD and Linux Containers Incus system container managers. By importing a specially crafted container image archive containing duplicate tar member headers, an authenticated attacker can replace the instance rootfs directory with a symbolic link pointing to the underlying host root filesystem. When performing file operations on a stopped container, the privileged forkfile helper binary resolves the symbolic link without confinement and chroots directly into the host filesystem, granting arbitrary root-level file read and write access.