Back to Blog
high SEVERITY6 min read

How path traversal happens in Ruby YARD server and how to fix it

A high-severity path traversal vulnerability (CVE-2026-41493) in YARD versions prior to 0.9.42 allowed attackers to read arbitrary files from servers running `yard server`. This fix upgrades the yard gem from 0.9.26 to 0.9.42 in the Gemfile and Gemfile.lock, closing a dangerous information disclosure vector that could expose configuration files, credentials, and source code.

O
By Orbis AppSec
•Technically reviewed by Anupam Mediratta•Published July 9, 2026•Reviewed July 9, 2026

Answer Summary

CVE-2026-41493 is a path traversal vulnerability in YARD, a Ruby documentation generator, affecting versions before 0.9.42. When running `yard server`, attackers could craft malicious URLs with `../` sequences to escape the documentation directory and read arbitrary files from the server, potentially exposing secrets and source code. The fix is to upgrade the yard gem to version 0.9.42 or later by updating your Gemfile constraint and running `bundle update yard`.

Vulnerability at a Glance

cweCWE-22 (Improper Limitation of a Pathname to a Restricted Directory)
fixUpgrade yard gem from 0.9.26 to 0.9.42 or later
riskUnauthorized file read access on servers running YARD documentation server
languageRuby
root causeYARD server did not properly sanitize file path parameters, allowing `../` traversal sequences
vulnerabilityPath Traversal / Directory Traversal

Introduction

In a Ruby project's Gemfile.lock, we discovered a high-severity path traversal vulnerability lurking in an outdated version of YARD—the popular Ruby documentation generator. The project was running yard version 0.9.26, which contained CVE-2026-41493, a flaw that could let attackers read arbitrary files from any server running yard server.

This isn't just a theoretical risk. YARD's built-in server is commonly used during development to browse generated documentation locally, but it's sometimes inadvertently exposed on staging or CI servers. The vulnerable code path didn't properly sanitize URL parameters, allowing an attacker to escape the documentation root directory using classic ../ traversal sequences.

Here's the vulnerable dependency declaration from the original Gemfile:

gem "yard", "~> 0.9.11"

This constraint allowed any version from 0.9.11 up to (but not including) 0.10.0, which meant the resolved version 0.9.26 in Gemfile.lock remained vulnerable to CVE-2026-41493.

The Vulnerability Explained

What is Path Traversal?

Path traversal occurs when an application accepts user input that specifies a file path without properly validating that the path stays within intended boundaries. Attackers exploit this by injecting directory traversal sequences like ../ (dot-dot-slash) to navigate up the directory tree and access files outside the allowed scope.

How YARD Server Was Vulnerable

YARD includes a built-in web server (yard server) that serves generated documentation over HTTP. When a user requests a documentation page, the server maps the URL path to files in the documentation directory. In versions prior to 0.9.42, the server failed to properly sanitize these path parameters.

An attacker could craft a malicious request like:

GET /../../../../etc/passwd HTTP/1.1
Host: vulnerable-yard-server:8808

Or on a Ruby application server:

GET /../../../config/database.yml HTTP/1.1
Host: vulnerable-yard-server:8808

The YARD server would resolve this path relative to the documentation root, but the ../ sequences would escape that directory entirely, allowing the attacker to read:

  • /etc/passwd — system user information
  • config/database.yml — database credentials
  • .env files — environment secrets
  • config/master.key — Rails encryption keys
  • Source code files — potentially revealing additional vulnerabilities

Real-World Attack Scenario

Imagine a CI/CD pipeline that runs yard server to generate and preview documentation before deployment. If this server is accessible on the internal network (or worse, exposed publicly), an attacker could:

  1. Discover the YARD server running on port 8808
  2. Send a traversal request: GET /../../../.env
  3. Retrieve AWS credentials, API keys, or database passwords
  4. Use those credentials to access production systems

The Gemfile.lock showed the project was locked to version 0.9.26:

yard (0.9.26)

This version was released years before the security fix, leaving a significant window of exposure.

The Fix

The fix is straightforward but critical: upgrade the yard gem to version 0.9.42 or later, where the path traversal vulnerability has been patched.

Before (Vulnerable)

Gemfile:

gem "yard", "~> 0.9.11"

Gemfile.lock:

yard (0.9.26)

After (Fixed)

Gemfile:

gem "yard", "~> 0.9.42"

Gemfile.lock:

yard (0.9.42)

Why This Change Works

The version constraint change from ~> 0.9.11 to ~> 0.9.42 accomplishes two things:

  1. Immediate fix: Forces Bundler to resolve to at least version 0.9.42, which contains the security patch
  2. Future protection: The pessimistic constraint (~>) still allows patch updates (0.9.43, 0.9.44, etc.) while preventing breaking changes from a potential 0.10.0 release

The YARD maintainers fixed the vulnerability in version 0.9.42 by implementing proper path canonicalization and containment checks. The server now:

  • Resolves the full absolute path of any requested file
  • Verifies the resolved path starts with the documentation root directory
  • Rejects requests that would escape the allowed directory

Changes Made

File Change
Gemfile Updated version constraint from ~> 0.9.11 to ~> 0.9.42
Gemfile.lock Resolved version updated from 0.9.26 to 0.9.42

Both files needed updating because:
- Gemfile declares the dependency constraint (what versions are acceptable)
- Gemfile.lock records the exact resolved version (what's actually installed)

Key Takeaways

  • YARD versions before 0.9.42 are vulnerable to CVE-2026-41493 — any project using yard server with an older version should upgrade immediately
  • The ~> 0.9.11 constraint was too permissive — it allowed vulnerable versions to be installed; pin to at least ~> 0.9.42 for security
  • Development tools can become attack vectors — even documentation generators like YARD can expose sensitive files if their servers are accessible
  • Path traversal in Ruby requires explicit containment checks — always verify resolved paths stay within allowed directories using File.expand_path() and prefix matching
  • Automated dependency scanning caught this issue — Trivy flagged the vulnerable version in Gemfile.lock, enabling a quick fix before exploitation

How Orbis AppSec Detected This

  • Source: HTTP request path parameter in YARD server URL routing
  • Sink: File system read operation in YARD's server request handler
  • Missing control: Path canonicalization and containment validation before file access
  • CWE: CWE-22 (Improper Limitation of a Pathname to a Restricted Directory)
  • Fix: Upgraded yard gem from 0.9.26 to 0.9.42, which implements proper path validation

Orbis AppSec detects issues like this automatically. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

CVE-2026-41493 serves as a reminder that even trusted development tools can harbor serious security vulnerabilities. A documentation generator might seem low-risk, but when it includes a web server that handles file paths, it becomes a potential attack vector for information disclosure.

The fix was simple—a one-line version constraint change in the Gemfile—but the impact of leaving it unfixed could have been severe: exposed credentials, leaked source code, and potential full system compromise.

Keep your dependencies updated, scan regularly for vulnerabilities, and remember that security applies to every component in your stack, not just your application code.

Prevention and further reading

Related Articles

critical

Lampa Desktop Auto-Update Heuristic Bypass: Execution of Unverified

Lampa Desktop's auto-update mechanism downloaded JavaScript and CSS from `raw.githubusercontent.com` using only heuristic validation—file size thresholds and string pattern matching—that attackers could trivially satisfy. The fix introduces cryptographic integrity verification by cross-referencing Git blob hashes from the GitHub Contents API, ensuring downloaded code matches the repository's authoritative state before execution.

high

adm-zip 0.6.0 Preserves SUID Bits From ZIPs: CVE-2026-102282

The `adm-zip` dependency resolved to 0.6.0 in this project's dependency tree, a version affected by CVE-2026-102282: during extraction it applies the Unix permission bits stored in each ZIP entry's external file attributes verbatim, including the setuid (`04000`), setgid (`02000`), and sticky bits. An attacker who controls an archive passed to `extractAllTo()` or `extractEntryTo()` can therefore have the extractor create a setuid binary owned by whatever user the extraction process runs as. The

high

requestInput() Type Confusion: NaN and Object Bypass in JavaScript

The `requestInput()` utility function lacked validation on its `type` parameter and failed to handle `NaN` results from float conversions, creating a type confusion weakness. An attacker could supply malformed inputs that propagate unhandled `NaN` values or unexpected object types through the type system. The fix adds explicit guards against `NaN` type parameters and rejects non-primitive type values.

critical

No Rate Limit on /api/uploads/presign Enables DoS

The `/api/uploads/presign` endpoint accepted unlimited concurrent requests to generate storage presigned URLs, giving an attacker a free lever to exhaust storage-provider quotas and server resources. The fix adds an `express-rate-limit` middleware capping each client to 30 requests per minute on that route.

high

CVE-2026-54673: builder-util-runtime Leaks Auth Headers on Redirect

electron-updater and electron-builder rely on builder-util-runtime to fetch update manifests and artifacts over HTTP. A flaw in that shared HTTP executor allowed credential headers attached to the original update-feed request to be re-sent after a redirect, exposing them to any host the redirect pointed to. The project fixes this by upgrading builder-util-runtime to 9.7.0 and collapsing a duplicate, older copy of the package that electron-updater had pinned on its own.

high

image-size 1.2.1 DoS: Zero-Valued Dimensions in Image Buffer Parser

A high-severity denial-of-service vulnerability in image-size 1.2.1 allows attackers to crash Node.js services using malicious image buffers with zero-valued dimensions. The fix removes the vulnerable `queue` dependency and tightens dimension validation in version 2.0.3.