CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-26187

CVE-2026-26187: escaping the Lake with a Path Traversal Two-Step

Alon Barad
Alon Barad
Software Engineer

Feb 13, 2026·6 min read·42 visits

Executive Summary (TL;DR)

lakeFS failed to properly sanitize file paths in its Local Block Adapter. Due to a missing trailing slash in a prefix check and loose namespace validation, attackers can use `../` sequences to access files outside their repo. Fixed in v1.77.0.

A critical path traversal vulnerability in the lakeFS Local Block Adapter allows authenticated users to break out of their storage namespace boundaries. By exploiting a weak prefix validation check and a namespace logic error, attackers can read and write files in sibling repositories or unrelated directories on the host filesystem.

The Hook: Git for Data, Holes for Hackers

lakeFS bills itself as "Git for data." It’s a slick piece of engineering that brings branching, committing, and rolling back to your massive object storage buckets (S3, Azure Blob, GCS). But not everyone runs lakeFS on the cloud. For local development, testing, or just smaller deployments, lakeFS includes a Local Block Adapter. This component acts as a translation layer, pretending your local filesystem is an object store.

The Local Block Adapter is supposed to be a sandbox. It takes a root directory—say, /var/lib/lakefs/—and promises that all data operations will stay strictly within that box. It manages repositories as subdirectories, keeping repo-A separate from repo-B. Ideally, this creates a hard boundary, preventing a user in one repository from peeking at the data in another.

But boundaries in code are only as strong as the logic verifying them. CVE-2026-26187 is the story of what happens when you verify the general neighborhood but forget to check the specific house address. It turns out, lakeFS was checking if you were on the right street, but it didn't care if you were breaking into the neighbor's basement.

The Flaw: A Tale of Two Bugs

This vulnerability is actually a "buy one, get one free" deal. It stems from two distinct logic failures in pkg/block/local/adapter.go that, when combined, allow for a delightful escape. The first is a classic Prefix Bypass. When the adapter checked if a requested file path was valid, it used strings.HasPrefix.

Here is the catch: strings.HasPrefix("/data/lakefs_secrets", "/data/lakefs") returns true. Why? Because structurally, the string /data/lakefs is literally the start of /data/lakefs_secrets. By failing to append a directory separator (like /) to the check, the code allowed access to any sibling directory that started with the same characters. It’s like a bouncer letting you into "Club 33" because your ID says "Club 3"—close enough, right?

The second flaw is a Namespace Escape. lakeFS manages data in "Namespaces" (roughly mapping to repositories). The code correctly calculated where a namespace should be, but it didn't enforce that the final file path stayed inside that specific namespace. It only checked if the file was inside the global adapter root. This meant that if I'm in repo-A, I could issue a request for ../../repo-B/sensitive_file. The global check looks at the path, sees it resolves to /var/lib/lakefs/repo-B/sensitive_file, nods its head because that is indeed under /var/lib/lakefs, and serves up the stolen data.

The Code: The Missing Slash

Let's look at the smoking gun. This is the vulnerable verification function found in pkg/block/local/adapter.go. It's short, sweet, and insecure.

// Vulnerable Code: The Prefix Bypass
func (l *Adapter) verifyRelPath(p string) error {
    // DANGER: No trailing separator on l.path
    if !strings.HasPrefix(filepath.Clean(p), l.path) {
        return fmt.Errorf("%s: %w", p, ErrBadPath)
    }
    return nil
}

Because l.path (the adapter root) isn't terminated with a slash, an attacker can access /lakefs_backup if the root is /lakefs. But it gets worse. Here is how parameters were extracted and constructed:

// Vulnerable Code: The Namespace Escape
p := path.Join(l.path, ptr.StorageNamespace[len(DefaultNamespacePrefix):], ptr.Identifier)
if err := l.verifyRelPath(p); err != nil {
    return "", err
}

The code blindly joins the root, the namespace, and the user-controlled Identifier. It then passes the result to the flawed verifyRelPath. Even if verifyRelPath was perfect, this logic is still flawed because it only asserts that the file is in the Adapter Root, not the Namespace.

Here is the fix introduced in commit cbc106275357302a834280f133265dc39f1384ce. Notice the two-step verification: first verify the namespace is valid, then verify the final path is strictly inside that namespace.

// Patched Code
// 1. Validate the Namespace directory itself
namespacePath := filepath.Clean(filepath.Join(l.path, ptr.StorageNamespace[len(DefaultNamespacePrefix):]))
if err := l.verifyRelPath(namespacePath); err != nil {
    return "", err
}
 
// 2. Validate the final path is INSIDE the namespace
p := filepath.Clean(filepath.Join(namespacePath, ptr.Identifier))
// Check 1: p != namespacePath (can't access root of namespace)
// Check 2: HasPrefix with Separator (prevents sibling access)
if p != namespacePath && !strings.HasPrefix(p, namespacePath+string(filepath.Separator)) {
    return "", fmt.Errorf("%s: %w", p, ErrBadPath)
}

The Exploit: Jumping the Fence

To exploit this, you need authenticated access to a lakeFS instance using the Local Block Adapter. The scenario is simple: you have access to Repo-A, but you want the juicy secrets in Repo-B. Both live under the same adapter root on the server's disk.

Step 1: Setup. Imagine the server stores data at /var/lib/lakefs/block/. Your repository (Repo-A) is at /var/lib/lakefs/block/repo-a/. The target (Repo-B) is at /var/lib/lakefs/block/repo-b/.

Step 2: The Traversal. You craft an API request to read an object. Instead of a normal filename like data.csv, you pass a malicious identifier: identifier = "../../repo-b/config/secrets.yaml"

Step 3: Execution. lakeFS constructs the path: path.Join("/var/lib/lakefs/block", "repo-a", "../../repo-b/config/secrets.yaml")

This resolves to: /var/lib/lakefs/block/repo-b/config/secrets.yaml

The vulnerable verifyRelPath checks: Does this path start with /var/lib/lakefs/block? Yes. The server reads the file from Repo-B and returns it to you, the user of Repo-A. You have just violated the tenant isolation.

The Impact: Why This Matters

In a single-tenant environment, this might seem like a low-risk bug—you are stealing your own data. But lakeFS is often deployed in environments where data governance is key. The promise of lakeFS is that you can have different repositories for different teams (e.g., Finance vs. Engineering), potentially on the same infrastructure.

Data Leakage: An engineer with access to a sandbox repository could read production financial data if it is stored on the same local adapter volume.

Data Integrity: This isn't just a read vulnerability. The Local Block Adapter supports writes. An attacker could overwrite files in sibling repositories, corrupting the "source of truth" or injecting malicious data into a production pipeline. Imagine overwriting a machine learning model in a different repo with a poisoned version.

Host Compromise (Limited): While the prefix check prevents you from going strictly above the adapter root (you can't read /etc/passwd unless the adapter root is /), the "Prefix Bypass" bug means if the admin named folders poorly (e.g., /data/lakefs and /data/lakefs_ssh_keys), you might be able to read sensitive host configuration files adjacent to the storage directory.

The Fix: Remediation

The fix is straightforward: Upgrade to lakeFS v1.77.0. The treeverse team patched this by enforcing strict directory separators in their prefix checks and ensuring that object paths are anchored to their specific namespace, not just the global root.

If you are a developer writing similar file-handling code in Go (or any language), learn from this:

  1. Always append the separator: When checking if Path A is inside Dir B, check if Path A starts with Dir B + os.PathSeparator.
  2. Scope correctly: If a user is authorized for a specific sub-folder, validate against that sub-folder, not the parent drive.
  3. Use filepath.Clean: Always resolve .. and . before performing security checks.

Official Patches

TreeverseGitHub Commit fixing the traversal vulnerability

Fix Analysis (1)

Technical Appendix

CVSS Score
8.1/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N

Affected Systems

lakeFS (Local Block Adapter)

Affected Versions Detail

Product
Affected Versions
Fixed Version
treeverse/lakeFS
Treeverse
< 1.77.01.77.0
AttributeDetail
CVE IDCVE-2026-26187
CVSS Score8.1 (High)
CWECWE-22 (Path Traversal)
VectorCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Affected Versions< 1.77.0
Fix Version1.77.0

MITRE ATT&CK Mapping

T1083File and Directory Discovery
Discovery
T1005Data from Local System
Collection
CWE-22
Path Traversal

Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Known Exploits & Detection

Patch Test CaseGo test case demonstrating reading a secret file from a sibling directory.

Vulnerability Timeline

Patch committed to main branch
2026-02-12
CVE-2026-26187 Published
2026-02-13
lakeFS v1.77.0 Released
2026-02-13

References & Sources

  • [1]GitHub Security Advisory
  • [2]NVD Entry

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•16 minutes ago•GHSA-QV4M-M73M-8HJ7
8.8

GHSA-qv4m-m73m-8hj7: Authenticated Arbitrary File Upload leading to Remote Code Execution in NotrinosERP

An authenticated remote code execution vulnerability exists in NotrinosERP (versions up to and including 1.0.0) within the Human Resource Management (HRM) module. Users with employee management permissions can upload arbitrary file types, including PHP scripts, which are written directly to a web-accessible directory. This allows for arbitrary code execution in the context of the web-server user.

Alon Barad
Alon Barad
1 views•6 min read
•about 1 hour ago•GHSA-XRMC-C5CG-RV7X
8.8

GHSA-XRMC-C5CG-RV7X: Security Bypass Vulnerability in safeinstall-cli Command Parser

A high-severity security bypass vulnerability exists in safeinstall-cli up to version 0.10.1. Due to multiple logical limitations in its shell command parsing mechanism (guard-parser), attackers can craft specific shell commands that completely evade the Agent Guard interceptor hooks. This allows arbitrary unverified installations and code executions on the developer system when executed by AI coding agents.

Alon Barad
Alon Barad
2 views•7 min read
•about 1 hour ago•GHSA-WM45-QH3G-V83F
7.7

GHSA-WM45-QH3G-V83F: Arbitrary Server-Side File Read and Exfiltration via Attachment Upload in mcp-atlassian

An arbitrary server-side file read vulnerability exists in the mcp-atlassian integration server. Remote clients utilizing SSE or HTTP transports can exploit the lack of directory containment on attachment-upload tools to resolve and read arbitrary host files, exfiltrating them directly to Atlassian Jira or Confluence.

Amit Schendel
Amit Schendel
3 views•8 min read
•about 2 hours ago•GHSA-G5R6-GV6M-F5JV
7.7

GHSA-G5R6-GV6M-F5JV: Arbitrary File Read and Exfiltration in mcp-atlassian via Missing Path Validation

A directory traversal vulnerability exists in the mcp-atlassian integration server prior to version 0.22.0. The confluence_upload_attachment tool fails to restrict the paths of uploaded files, allowing authenticated users or external prompt injection payloads to retrieve and exfiltrate arbitrary files from the server's filesystem into Confluence.

Amit Schendel
Amit Schendel
3 views•7 min read
•about 2 hours ago•CVE-2026-54158
9.9

CVE-2026-54158: Stored Cross-Site Scripting to Host Remote Code Execution in SiYuan

A critical-severity Stored Cross-Site Scripting (XSS) vulnerability exists in the SiYuan personal knowledge management system. Due to missing sanitization in the attribute-view cell renderer and an insecure Electron default configuration (nodeIntegration: true), attackers can execute arbitrary commands on the victim's host operating system through synchronized workspaces.

Alon Barad
Alon Barad
6 views•5 min read
•about 3 hours ago•CVE-2026-50551
9.9

CVE-2026-50551: Stored Cross-Site Scripting to Remote Code Execution via Attribute View Asset Cell Renderer in SiYuan

A critical-severity stored Cross-Site Scripting (XSS) vulnerability exists in SiYuan's Attribute View database asset cell renderer. This flaw allows low-privilege authenticated users to execute arbitrary JavaScript in the application frontend. In Electron-based desktop clients, this execution context can be leveraged to execute arbitrary native operating system commands, resulting in complete system compromise.

Amit Schendel
Amit Schendel
5 views•6 min read