CVE Watchtower

← Back to CVE List

CVE-2026-74043NVD

Vulnerability Summary

Summary The `@expose_resources` framework upload helpers `upload_list_file`, `upload_rule_file`, and `upload_decoder_file` build their destination path from a caller-supplied `filename` with no traversal validation of their own — that check exists only in the REST API controller. They are reachable two ways: path 1 REST controller (validates filename) -> upload helper path 2 as_wazuh_object -> DistributedAPI(request) -> upload helper => path 2 skips the controller; filename is never validated A malicious/compromised cluster worker uses the second path: it hands the master a DAPI request whose `f` is one of these exposed helpers and whose `f_kwargs.filename` contains `../` traversal, producing an arbitrary-path file write as the `wazuh` user. This is the same primitive CVE-2026-25770 fixed for the cluster file-sync path (`receive_file`), reached via a code path that fix did not cover. The upload helpers did not become newly exposed; they became reachable through a path that bypasses the validation layer they implicitly relied upon. Details 1. The exposed-resource gate (`_wazuh_exposed_`, #34889) lets the `as_wazuh_object` callable branch resolve these functions — they are legitimately `@expose_resources`-decorated. The gate checks the callable's identity, not its arguments. 2. No framework-layer `filename` validation: - `cdb_list.upload_list_file`: the only guard, `get_filenames_paths([filename])[0] != full_path`, is ineffective — `get_filenames_paths` uses `Path(root).rglob(filename)`, which never matches a `../` pattern, so it returns the default (== `full_path`) and the `!=` guard never fires. - `rule.upload_rule_file` / `decoder.upload_decoder_file`: `validate_upload_delete_dir` validates only `relative_dirname`; `filename` is unvalidated. `full_path = join(WAZUH_PATH, relative_dirname, filename)`. 3. `upload_file` delegates to `safe_move` (core/utils.py), a generic move utility that assumes the destination was already validated by the caller (no bounds check of its own). 4. Traversal protection lives only in the REST controller format validators (`_cdb_filename_path = ^[\-\w]+$`, `_xml_filename_path = ^[\w\-]+\.xml$`, `api/validator.py:41-42`), which the callable branch never invokes. 5. On the master, `APIRequestQueue.run` (dapi.py:714-720) does `request = json.loads(request, object_hook=as_wazuh_object)` then `DistributedAPI(request, ...)` — the wire request dict is splatted in with no re-verification of `rbac_permissions` against the sending node. A request that omits `rbac_permissions` inherits the constructor default `{'rbac_mode':'black'}` (dapi.py:111), which permits the action. Reachability: (a) `as_wazuh_object` resolves these functions as `f` (they pass the exposed-resource gate); (b) `run_local` calls `f(**f_kwargs)` with attacker `f_kwargs` (dapi.py:243-246, the same execution point as CVE-2026-25769); (c) the function performs the unvalidated-`filename` write. Only the Fernet-socket transport (the same one already demonstrated by CVE-2026-25769) was intentionally left out of scope. PoC Isolated 2-node lab, two `wazuh/wazuh-manager:4.14.6`, shared cluster key. The PoC invokes the framework upload functions directly in-process to demonstrate the write primitive (rbac harness set to the `DistributedAPI` default `{'rbac_mode':'black'}`, not a privileged assumption). Harmless target inside the container's `/var/tmp`. Rule (well-formed XML content): ``` upload_rule_file(relative_dirname="etc/rules", filename="../../../tmp/POC_RULE_TRAVERSAL", content='<group name="poc_traversal"></group>', overwrite=True) -> writes /var/tmp/POC_RULE_TRAVERSAL (outside /var/ossec); result "Rule was successfully uploaded" ``` CDB (content-constrained): ``` upload_list_file(filename="../../../tmp/POC_CDB_TRAVERSAL", content="poc:cdb_traversal_write_proof", overwrite=True) -> writes /var/tmp/POC_CDB_TRAVERSAL ``` Guard-bypass shown independently: `get_filenames_paths(["../.."])[0] == join(USER_LISTS_PATH, "../..")`. Full reproduction transcript and scripts attached. Source-diff scoping the novelty (v4.14.2 vulnerable -> v4.14.6): the CVE-2026-25770 fix changed only `receive_file` (4.14.2 `open(common.WAZUH_PATH + data.decode(), 'wb')` -> 4.14.6 `realpath` + `_ALLOWED_PREFIXES`); `upload_list_file`, `upload_rule_file`, `validate_upload_delete_dir`, `safe_move`, and `upload_file` are byte-identical between v4.14.2 and v4.14.6 — i.e. never touched by that fix. Still source-identical on the 4.14.8 dev branch. Impact Arbitrary-path file write as the `wazuh` service user, reachable by a compromised/malicious cluster worker (requires the cluster key — same trust model as CVE-2026-25769/25770). Demonstrated: the write primitive (High). Not developed (deliberate scope limit): chaining `upload_rule_file` with `filename="../../etc/ossec.conf"` + valid XML to inject a `<localfile>` command block executed as root by `wazuh-logcollector` — i.e. the CVE-2026-25770 root-RCE outcome, via this different, still-unpatched code path. Suggested fix Validate `filename` at the framework layer in the three upload functions: resolve the final destination and verify it stays beneath the intended base directory before moving the file — the same `realpath` + `_ALLOWED_PREFIXES` commonpath check the CVE-2026-25770 fix already added to `receive_file` (common.py:1000-1002). Do not rely on controller-layer format validation for functions reachable via the cluster callable path. Scope / disclosure note This report demonstrates the file-write primitive only; the ossec.conf->root-RCE chain and the Fernet-socket network delivery were intentionally not developed (responsible disclosure). Offered framing: an incomplete fix / variant of CVE-2026-25770 — new-CVE vs 25770-variant is left to the vendor. poc_rule_traversal.py test_cdb_guard.py verify_25769.py verify_layer2.py evidence-run.txt poc_cdb_traversal.py
Severity Level
CRITICAL(9.0)
Published Date
Oct 13, 2026
Last Modified
Oct 13, 2026
Exploitation Status
No confirmed exploitation yet
CVE Record Status
Reserved
This CVE ID is referenced in a public advisory, but the CVE Program has not published its official CVE Record yet. Full CVSS/CPE data from NVD will appear here once it does.
EPSS Score (30-Day)
Data Pending
Root Weakness (CWE)
The software uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory.
Refer to the official MITRE database for detailed architectural specifications regarding this weakness.
CVSS v3.1 Base Metrics — Score 9.0
Attack VectorNetwork
Attack ComplexityLow
Privileges RequiredHigh
User InteractionNone
ScopeChanged
ConfidentialityLow
IntegrityHigh
AvailabilityHigh

Affected & Patched Versions

Affected Versions
  • wazuh-manager >= 4.1.1
Patched Versions
  • wazuh-manager 4.14.8
🎁7-Day Free Trial — Try Pro or Team, no card required.
📧Email Delivery — Threat intel straight to your inbox.
♾️Unlimited Vendors — Track your entire stack.
🚨All New CVEs — Be the first to know.
📈EPSS Spike Alerts — Catch rising risk before it peaks.
🎯Custom EPSS/CVSS — Filter noise, focus on risk.
🛡️Exploit Intel — A 2nd confirmed-exploit signal beyond KEV.
🐙GitHub Issues — Auto-tracked, no duplicates.
📬Weekly Digest — One clean summary, not inbox spam.
🏷️Watchlist Groups — Tag alerts by team (Infra/AppSec/SOC).
💬Webhooks — Slack & Teams integration.
🔀Smart Routing — Critical alerts to one channel, rest to another.
🚫Ad-Free — Uninterrupted experience.
🎁7-Day Free Trial — Try Pro or Team, no card required.
📧Email Delivery — Threat intel straight to your inbox.
♾️Unlimited Vendors — Track your entire stack.
🚨All New CVEs — Be the first to know.
📈EPSS Spike Alerts — Catch rising risk before it peaks.
🎯Custom EPSS/CVSS — Filter noise, focus on risk.
🛡️Exploit Intel — A 2nd confirmed-exploit signal beyond KEV.
🐙GitHub Issues — Auto-tracked, no duplicates.
📬Weekly Digest — One clean summary, not inbox spam.
🏷️Watchlist Groups — Tag alerts by team (Infra/AppSec/SOC).
💬Webhooks — Slack & Teams integration.
🔀Smart Routing — Critical alerts to one channel, rest to another.
🚫Ad-Free — Uninterrupted experience.