NewN-Day-BenchView benchmark
winfunc
Back to Hacktivity

Status: Patched

This vulnerability has been verified as resolved and deployed.

Meltano logo
MeltanoHigh2026-07-22

Traversing include paths allow cross-project YAML overwrite

Summary

Included YAML paths were checked for existence but not canonical project-root containment

A contributor to a lower-trust Meltano project could add a traversing include_paths pattern and cause an operator's routine configuration mutation to replace or blank a writable sibling project's valid YAML configuration.

Root cause. ProjectFiles._resolve_include_paths() accepted any glob match that existed and was a file. ProjectFiles.update() later treated every accepted match as an authorized persistence destination, and _write_file() performed an atomic replacement without rechecking containment.

Remediation evidence. Meltano confirmed the report and opened exact PR #10182 two days later; it merged on 22 July 2026. The patch enforces canonical project-root containment at resolution and again at the write sink, including traversal and symlink regression tests.

CVSS Score

VectorL
ComplexityL
PrivilegesL
User InteractionR
ScopeC
ConfidentialityN
IntegrityH
AvailabilityH
CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:N/I:H/A:H

Vulnerability Location

SourceLine 67
src/meltano/core/project_files.py
ProjectFiles.include_paths
SinkLine 375
src/meltano/core/project_files.py
ProjectFiles._write_file()

Source-to-Sink Analysis

1
src/meltano/core/project_files.py:67

The contributed project supplies a relative glob that resolves to an existing sibling YAML file.

PYTHON
include_paths:
  - ../privileged-project/meltano.yml
2
src/meltano/core/project_files.py:_resolve_include_paths()

The vulnerable resolver verified only file existence/type and retained the external path.

PYTHON
for path in self.root.glob(pattern):
    self._is_valid_include_path(path)
    include_paths.append(path)
3
src/meltano/core/project_files.py:375

A normal environment/plugin mutation serializes merged configuration and atomically replaces the out-of-root destination.

PYTHON
fd, tmp_name = tempfile.mkstemp(dir=file_path.parent)
# serialize YAML to tmp_name
os.replace(tmp_name, file_path)

Impact Analysis

Critical Impact

The attacker can corrupt or destroy another project's plugin, environment, schedule, or job configuration, crossing the repository/project trust boundary and causing material integrity and availability impact.

Attack Surface

Meltano projects that accept contributor-controlled meltano.yml changes and are processed by an operator or CI identity with write access to sibling paths.

Preconditions

The attacker can modify one project's configuration but cannot directly write the target project. An operator or CI job must run a normal Meltano configuration mutation, and the process account must be able to replace the target file.

Proof of Concept

Environment Setup

Create two disposable sibling Meltano projects under one writable parent directory and seed the victim project with a valid configuration plus a unique marker.

Target Configuration

In the attacker project, set include_paths to ../victim/meltano.yml without granting the attacker direct victim-directory access in the collaboration model.

Exploit Delivery

Run a normal write-producing Meltano command against the attacker project, such as adding an environment or plugin.

Outcome

PR #10182 rejects the external canonical path and preserves the victim marker; legitimate in-project includes continue to work.

Expected Response: On the vulnerable release, the victim file's bytes change or the file is replaced with the blank-subfile serialization.

Run this level of analysis on your repo.

Winfunc traces source-to-sink paths, validates exploitability, and gives your team patch-ready remediation.

Vulnerability Detection