Skip to content

CVE-2026-23535: Verified Repro With Script Download

CVE-2026-23535: wlc: Path traversal via unsanitized API slugs in download command

CVE-2026-23535 is verified against wlc · pip. Affected versions: wlc < 1.17.2. Fixed in wlc 1.17.2. Vulnerability class: Path Traversal. This high reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00070.

REPRO-2026-00070 wlc · pip Path Traversal Jan 17, 2026 CVE entry ↗ .txt
Severity
HIGH
CVSS
8.0
Reproduced in
20m 59s
Tool calls
216
Spend
$3.97
01 · Overview

What Is CVE-2026-23535?

CVE-2026-23535 is a high-severity path traversal in the Weblate command-line client (wlc) before 1.17.2. A malicious Weblate server can make the client write files to an arbitrary location during a multi-translation download. Pruva reproduced it (reproduction REPRO-2026-00070).

02 · Severity & CVSS

CVE-2026-23535 Severity & CVSS Score

CVE-2026-23535 is rated high severity, with a CVSS base score of 8.0 out of 10.

HIGH threat level
8.0 / 10 CVSS base
Weakness CWE-22 — Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

High — serious impact or readily exploitable. Prioritize remediation.

03 · Affected Versions

Affected wlc Versions

wlc · pip versions wlc < 1.17.2 are affected.

How to Reproduce CVE-2026-23535

$ pruva-verify REPRO-2026-00070
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00070/artifacts/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-23535

Reproduced by Pruva's autonomous agents — 216 tool calls over 21 min. Full root-cause analysis and the complete transcript are below.

How the agent worked 670 events · 216 tool calls · 21 min
21 minDuration
216Tool calls
226Reasoning steps
670Events
5Dead-ends
Agent activity over 21 min
Support
10
Repro
280
Coding
377
0:0020:59

Root Cause and Exploit Chain for CVE-2026-23535

Summary

A malicious Weblate server can abuse the wlc download command’s multi-component workflow to write files outside the caller’s chosen output directory. The client trusts component metadata returned by the server and uses the embedded project slug verbatim when constructing the zip filename, allowing absolute paths to be honored and causing arbitrary file writes on the filesystem running wlc < 1.17.2.

Impact

  • Package: Weblate wlc CLI
  • Affected versions: All releases prior to 1.17.2
  • Risk: High – a crafted server (or MITM) can force the client to overwrite arbitrary files (e.g., /etc/cron.d/...) during wlc download --multi, leading to privilege escalation or system compromise on any machine that runs the command.

Root Cause

wlc.main.Download.download_component() builds the destination path as Path(output_dir) / f"{component.project.slug}-{component.slug}.zip". The values component.project.slug and component.slug come directly from API responses without sanitization. When a malicious server returns an absolute path such as /tmp/weblate-owned for the project slug, pathlib.Path treats it as an absolute path and drops the intended base directory, writing the downloaded archive to that attacker-chosen location. The issue is fixed upstream in https://github.com/WeblateOrg/wlc/pull/1128 (released in 1.17.2) which normalizes and validates slugs before using them in filesystem paths.

Reproduction Steps

  1. Run repro/reproduction_steps.sh.
  2. The script provisions a Python venv, installs wlc==1.17.1, starts a mock Weblate HTTP server that serves a component listing whose project slug is /tmp/weblate-owned, and then executes wlc download --output repro-output against it.
  3. Successful reproduction is indicated by creation of /tmp/weblate-owned-absolute-component.zip (outside the requested output directory) and logs stored in logs/.

Evidence

  • Log artifacts: logs/mock_server.log, logs/wlc_download.log, logs/evidence.txt.
  • Key excerpt (logs/evidence.txt):
    • -rw-r--r-- 1 root root 58 ... /tmp/weblate-owned-absolute-component.zip
    • Intended output directory repro-output/ remains empty, proving the write escaped the sandbox.
  • Environment: Python 3.11 virtualenv with wlc==1.17.1 on Ubuntu (container) as provisioned by the script.

Recommendations / Next Steps

  • Upgrade wlc clients to 1.17.2 or later, which sanitizes slugs before constructing output paths.
  • For additional defense-in-depth, consider enforcing a jail by resolving all download outputs relative to the configured directory and rejecting absolute inputs from the server.
  • Add regression tests that simulate malicious slugs to ensure future changes preserve the validation.

Additional Notes

  • repro/reproduction_steps.sh is idempotent: running it twice in succession succeeds, recreating the evidence and overwriting the malicious file each time.
  • The mock server only implements the minimal endpoints needed for this PoC; real-world instances may require authentication, but the vulnerability manifests regardless once the client processes attacker-controlled component metadata.

CVE-2026-23535 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:001:06
0:00
session startedgpt-5.1-codex · ghsa-mmwx-79f6-67jg · ghsa-mmw
0:06
0:06
extract_facts
no facts extracted
0:14
0:14
extract_facts
no facts extracted
0:14
error

Unknown error

0:18
0:18
0:18
supportrepro
0:26
0:26
0:28
0:28
0:29
0:29
0:31
0:31
0:32
0:32
0:34
0:34
0:35
0:35
0:42
0:42
0:48
1:02
$cd /root/.pruva/runs/ghsa-mmwx-79f6-67jg_20260117-214540 && python3 -m venv venv && /root/.pruva/runs/ghsa-mmwx-79f6-67jg_20260117-214540/venv/bin/pip install --upgrade pip setuptools wheel
13.8s
Requirement already satisfied: pip in ./venv/lib/python3.11/site-packages (24.0)
Collecting pip
  Using cached pip-25.3-py3-none-any.whl.metadata (4.7 kB)
Requirement already satisfied: setuptools in ./venv/lib/python3.11/site-packages (79.0.1)
Collecting setuptools
  Using cached setuptools-80.9.0-py3-none-any.whl.metadata (6.6 kB)
Collecting wheel
  Using cached wheel-0.45.1-py3-none-any.whl.metadata (2.3 kB)
1:06

Artifacts and Evidence for CVE-2026-23535

Scripts, logs, diffs, and output captured during the reproduction.

No artifacts available

08 · How to Fix

How to Fix CVE-2026-23535

Upgrade wlc · pip to wlc 1.17.2 or later.

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-23535 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-23535

What has to happen to exploit CVE-2026-23535?

The user must run wlc download against a malicious or compromised Weblate server, which returns component metadata with a path-traversing or absolute-path project slug — causing arbitrary file writes on the machine running wlc.

Which versions of wlc are affected by CVE-2026-23535, and where is it fixed?

wlc (the Weblate CLI) versions before 1.17.2 are affected. It is fixed in 1.17.2 — upgrade to 1.17.2 or later.

How can I reproduce CVE-2026-23535?

Download the verified script from this page and run it in an isolated environment with wlc < 1.17.2 pointed at a crafted Weblate server. The server returns a project slug with an absolute/traversing path and the client writes the download outside the intended directory.
11 · References

References for CVE-2026-23535

Authoritative sources for CVE-2026-23535 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.