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
Published July 9, 2026Reviewed 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)

Prevention & Best Practices

1. Keep Dependencies Updated

Regularly audit and update your dependencies. Tools like bundle audit for Ruby can identify known vulnerabilities:

gem install bundler-audit
bundle audit check --update

2. Use Dependency Scanning in CI/CD

Integrate security scanners like Trivy, Dependabot, or Snyk into your pipeline to catch vulnerable dependencies before they reach production.

3. Minimize Exposure of Development Tools

YARD server is intended for local documentation browsing, not production use. Ensure development tools like yard server are:
- Never exposed to the internet
- Firewalled on CI/CD systems
- Disabled in production environments

4. Implement Defense in Depth

Even if you're running a patched version, apply additional protections:
- Use reverse proxies with path validation
- Run services in containers with minimal file system access
- Apply the principle of least privilege

5. Validate File Paths in Your Own Code

When building applications that handle file paths, always:

# Bad - vulnerable to path traversal
file_path = params[:filename]
File.read(file_path)

# Good - validate and contain the path
base_dir = Rails.root.join('public', 'documents')
requested_file = File.expand_path(params[:filename], base_dir)

unless requested_file.start_with?(base_dir.to_s)
  raise SecurityError, "Path traversal attempt detected"
end

File.read(requested_file)

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 automatically detected this vulnerability and opened a pull request with the fix. 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.

References

Frequently Asked Questions

What is path traversal?

Path traversal (also called directory traversal) is a vulnerability where an attacker manipulates file path inputs using sequences like `../` to access files outside the intended directory, potentially reading sensitive system files or application secrets.

How do you prevent path traversal in Ruby?

Validate and sanitize all user-supplied path inputs, use `File.basename()` to strip directory components, check that resolved paths stay within allowed directories using `File.expand_path()`, and keep dependencies like YARD updated to patched versions.

What CWE is path traversal?

Path traversal is classified as CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

Is input validation enough to prevent path traversal?

Input validation helps but isn't always sufficient alone. You should combine validation with canonicalization (resolving the full path) and containment checks to verify the final path stays within allowed boundaries. Using patched libraries is also essential.

Can static analysis detect path traversal?

Yes, static analysis tools like Trivy, Semgrep, and Brakeman can detect path traversal patterns by tracking tainted input flowing into file system operations without proper sanitization.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #30117

Related Articles

high

How Authentication Bypass happens in PyJWT and how to fix it

A critical authentication bypass vulnerability in PyJWT 2.12.1 allowed attackers to forge valid JSON Web Tokens, potentially bypassing application authentication mechanisms entirely. The vulnerability was fixed in PyJWT 2.13.0 through security improvements to token validation logic. This fix is essential for any application relying on JWT-based authentication.

high

How unsafe pickle deserialization happens in Keras/TensorFlow notebooks and how to fix it

A high-severity untrusted deserialization vulnerability was discovered in `TransferLearningTF.ipynb`, a transfer learning tutorial notebook that loads VGG16 model weights from the internet without verifying their integrity. Because Keras relies on Python's pickle-based serialization format under the hood, a tampered or substituted weights file could execute arbitrary code with the full privileges of the notebook user. The fix adds a SHA-256 checksum verification step immediately after the weight

critical

How Chromium launch-argument injection happens in Python Crawl4AI and how to fix it

A critical unauthenticated remote code execution vulnerability in Crawl4AI 0.8.9 allowed attackers to inject arbitrary Chromium launch arguments through the `browser_config.extra_args` parameter, potentially taking full control of the host process. The fix upgrades to Crawl4AI 0.9.0 and refactors the crawler initialization in `agent/tools/crawler.py` to use the new `BrowserConfig` and `CrawlerRunConfig` APIs, which enforce proper argument validation. This change eliminates the injection surface

critical

How integer overflow in buffer size calculation happens in C++ and how to fix it

A critical integer overflow vulnerability was discovered in OpenCV's HAL filter implementation where multiplying image dimensions without overflow protection could allocate dangerously undersized buffers. An attacker supplying crafted image dimensions (e.g., 65536×65536) could trigger heap corruption through out-of-bounds writes. The fix promotes the calculation to 64-bit arithmetic with a single cast.

critical

How buffer overflow via strcpy() happens in C zlib and how to fix it

A critical buffer overflow vulnerability was discovered in `general/libzlib/gzlib.c` where multiple `strcpy()` and `strcat()` calls operated without bounds checking. An attacker controlling file paths or error messages could overflow destination buffers, potentially achieving arbitrary code execution. The fix replaces these unsafe string operations with bounded `memcpy()` calls that respect pre-calculated buffer lengths.

critical

How hardcoded API key placeholders in documentation happen in Python and how to fix it

A high-severity security issue was discovered in the Context7 API documentation where a hardcoded API key placeholder (`CONTEXT7_API_KEY`) could be copied directly into production code. The fix replaced the static string with a proper environment variable reference using `os.environ`, preventing developers from accidentally deploying exposed credentials.