Bug 2558499 - CVE-2026-85518 openscap: openscap: Arbitrary file write via path traversal in Source DataStream decomposition [fedora-rawhide]
Summary: CVE-2026-85518 openscap: openscap: Arbitrary file write via path traversal in...
Keywords:
Status: NEW
Alias: None
Product: Fedora
Classification: Fedora
Component: openscap
Version: rawhide
Hardware: Unspecified
OS: Unspecified
medium
medium
Target Milestone: ---
Assignee: Michal Ambroz
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard: {"flaws": ["a992a44f-f890-4782-8591-a...
Depends On:
Blocks: CVE-2026-85518
TreeView+ depends on / blocked
 
Reported: 2026-10-21 19:24 UTC by Marco Benatto
Modified: 2026-10-21 19:24 UTC (History)
7 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Marco Benatto 2026-10-21 19:24:05 UTC
Disclaimer: Community trackers are created by Red Hat Product Security team on a best effort basis. Package maintainers are required to ascertain if the flaw indeed affects their package, before starting the update process.

AI_ONLY_REPORT
package: openscap-1.4.4-1.hum1
------
Summary: Path traversal in SDS decomposition allows writes outside intended  
target directory: attacker-controlled `cat:uri/@name` values can escape the  
selected decomposition output tree and cause filesystem writes outside that  
directory under the permissions of the OpenSCAP process.
Requirements to exploit: An attacker must supply a crafted Source  
DataStream containing a malicious `catalog/uri/@name` value and have a user  
or calling application run the SDS decomposition workflow that writes  
component files to disk. No prior account is required, but exploitation  
depends on that workflow being invoked and any resulting writes are limited  
to the permissions of the `openscap` process.
Component affected: `openscap-1.4.4-1.hum1`, specifically the SDS  
decomposition and component dump path in `src/DS/sds.c` and  
`src/DS/ds_common.c`, with recursive parent-directory creation in  
`src/common/oscap_acquire.c`
Version affected: `openscap-1.4.4-1.hum1`
Patch available: no released package fix established; proposed patch  
included below
Version fixed: unknown
Upstream coordination: Reported directly to the maintainer in this report.
CVSS: CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:L - 6.1 (MEDIUM)
AV:L - The established attack path is delivery of a crafted SDS file to  
a local or locally invoked decomposition workflow, not unauthenticated  
network reachability.
AC:L - The exploit uses straightforward `../` path traversal in  
catalog-provided names; no race or unusual preconditions are shown beyond  
getting the malicious SDS processed.
PR:N - The attacker does not need an account on the target system to  
prepare the malicious datastream.
UI:R - A user or higher-level application must process the  
attacker-supplied SDS content through the decomposition path.
S:U - The impact stays within the privileges and authority of the  
affected process; no separate security scope transition is established.
C:N - The observed behavior is unauthorized write outside the intended  
output directory; direct data disclosure is not established.
I:H - The flaw allows attacker-chosen filesystem writes outside the  
intended extraction tree, which can materially compromise integrity within  
the process's write permissions.
A:L - Misplaced writes can disrupt operation or corrupt expected files,  
but broad service unavailability is not established from the available  
evidence.
Impact: Moderate. Under Red Hat's severity guidance, this issue can  
compromise integrity by allowing writes outside the intended extraction  
directory, but it is not an easy remote unauthenticated compromise.  
Exploitation depends on attacker-supplied SDS content being processed  
through a specific file-writing workflow, likely with user or application  
involvement, and the demonstrated impact remains bounded by the privileges  
of the `openscap` process rather than direct system compromise.
Embargo: no
Reason: The currently established impact is Moderate, requires  
processing attacker-supplied SDS content through a specific workflow, and  
has straightforward operational mitigations such as refusing unsafe path  
segments or avoiding decomposition of untrusted datastreams until fixed.
Acknowledgement: Aisle Research
Vulnerability Details: Within the SDS decomposition flow, the `name`  
attribute of a catalog `uri` element is treated as a relative output path  
and recursively propagated into later component extraction. The following  
exact lines show the attacker-controlled `name` value entering the  
recursive path and later becoming the saved filename:
```c
char* name = (char*)xmlGetProp(uri, BAD_CAST "name");
...
if (ds_sds_dump_component_ref_as(cat_component_ref, session,  
target_filename_dirname, name) != 0)
...
struct oscap_source *component_source =  
oscap_source_new_from_xmlDoc(new_doc, relative_filepath);
...
char *filename = target_dir == NULL ?  
oscap_strdup(oscap_source_readable_origin(s))
: oscap_sprintf("%s/%s", target_dir, oscap_source_readable_origin(s));
int ret = oscap_acquire_ensure_parent_dir(filename);
...
ret = oscap_source_save_as(s, filename);
```
In the same path, `oscap_acquire_ensure_parent_dir()` derives the parent  
directory with `oscap_dirname()` and forwards it to  
`oscap_acquire_mkdir_p()` without checking whether the resulting path stays  
within the caller's intended base directory. As a result, a crafted `name`  
such as `../../tmp/oscap-poc/evil.xml` can escape the chosen `target_dir`  
and cause directory creation and file writes elsewhere on the filesystem.  
The practical issue established here is relative-path traversal; the  
available evidence does not require absolute-path handling to demonstrate  
impact. The demonstrated reachability is the SDS decomposition flow that  
registers components with dependencies and later dumps component files, and  
this report does not assume broader reachability for unrelated package  
functionality.
Steps to reproduce:
1. Prepare a valid Source DataStream XML containing a `catalog` entry whose  
`uri/@name` includes traversal, for example `../../tmp/oscap-poc/evil.xml`,  
and whose `uri/@uri` points to a valid component reference such as `#...`.
2. Invoke an SDS decomposition path that writes component files, for  
example via the library/API flow using  
`ds_sds_session_register_component_with_dependencies(...)` followed by  
`ds_sds_session_dump_component_files(...)`.
3. Set the output target directory to a controlled location such as `./out`.
4. Run the decomposition on the crafted SDS.
5. Observe that directories and files are created outside `./out`, for  
example under `../../tmp/oscap-poc/` relative to the process working  
directory, instead of being rejected as unsafe.
Mitigation: Do not decompose untrusted SDS content until a fix is  
available. If decomposition of externally supplied datastreams is  
unavoidable, reject any `catalog/uri/@name` value containing `..`, a  
leading `/`, or other path elements that escape the intended base directory  
before invoking the workflow, and run decomposition under a dedicated  
low-privilege account with a tightly restricted writable directory.
Proposed Fix: Validate SDS-derived relative paths before directory creation  
and keep all component writes confined to the caller-specified base  
directory. A minimal patch is shown below.
```diff
diff --git a/src/common/oscap_acquire.c b/src/common/oscap_acquire.c
index XXXXXXX..YYYYYYY 100644
— a/src/common/oscap_acquire.c
+++ b/src/common/oscap_acquire.c
@@
+static bool _oscap_path_has_unsafe_segments(const char *p)
+{
+    if (p == NULL || *p == '\0') return true;
+    if (p[0] == '/') return true;                    // absolute path
+    if (strcmp(p, "..") == 0) return true;
+    if (strncmp(p, "../", 3) == 0) return true;
+    if (strstr(p, "/../") != NULL) return true;
+    size_t n = strlen(p);
+    if (n >= 3 && strcmp(p + n - 3, "/..") == 0) return true;
+    return false;
+}
+
+int oscap_acquire_ensure_parent_dir_with_base(const char *base, const char  
*relative_filepath)
+{
+    if (_oscap_path_has_unsafe_segments(relative_filepath)) {
+        oscap_seterr(OSCAP_EFAMILY_OSCAP, "Refusing unsafe relative  
path '%s'.", relative_filepath);
+        return -1;
+    }
+    char *full = oscap_path_join(base, relative_filepath);
+    int ret = oscap_acquire_ensure_parent_dir(full);
+    free(full);
+    return ret;
+}
diff --git a/src/DS/ds_common.c b/src/DS/ds_common.c
index XXXXXXX..YYYYYYY 100644
— a/src/DS/ds_common.c
+++ b/src/DS/ds_common.c
@@
       char *filename = target_dir == NULL ?  
oscap_strdup(oscap_source_readable_origin(s))

               : oscap_sprintf("%s/%s", target_dir,  
oscap_source_readable_origin(s));

       int ret = oscap_acquire_ensure_parent_dir(filename);
+        const char *origin = oscap_source_readable_origin(s);
+        char *filename = target_dir == NULL ? oscap_strdup(origin)
+                : oscap_path_join(target_dir, origin);
+        int ret = (target_dir == NULL)
+                ? oscap_acquire_ensure_parent_dir(filename)
+                : oscap_acquire_ensure_parent_dir_with_base(target_dir,  
origin);
```


Defense in depth: an `openat`/`mkdirat`-based implementation with  
`O_NOFOLLOW` would further reduce symlink-related risk.
------
This report was generated using AI technology. Always review AI-generated  
content prior to use


Note You need to log in before you can comment on or make changes to this bug.