A critical vulnerability in Ruby on Rails Active Storage lets unauthenticated attackers read arbitrary server files and achieve remote code execution through crafted MATLAB file uploads. Tracked as CVE-2026-66066 with a CVSS 9.5 score, the flaw affects Rails 6.0 through 8.1 when using the default libvips image processor. Patches landed July 29, 2026, in Rails 7.2.3.2, 8.0.5.1, and 8.1.3.1. Applications that cannot upgrade immediately must set VIPS_BLOCK_UNTRUSTED=1 or call Vips.block_untrusted(true) with libvips 8.13+ and ruby-vips 2.2.1+.
Vulnerability Details
CVE-2026-66066 (nicknamed KindaRails2Shell) is an arbitrary file read vulnerability in Active Storage's variant processing pipeline that escalates to remote code execution. The vulnerability carries a CVSS 3.1 score of 9.5 (Critical).
Root Cause
The flaw sits at the trust boundary between Active Storage and libvips. Active Storage accepts user-uploaded files and processes them with libvips to generate thumbnails. However, Active Storage did not enable libvips's built-in protection against "untrusted" image loaders -- loaders for exotic formats like MATLAB (.mat), FITS, NIfTI, SVG, and others that libvips flags as unsafe for hostile input.
Attack Vector
An attacker crafts a MATLAB v7.3 (.mat) file exploiting HDF5 external dataset references. The file header declares MATLAB 5.0 (which libvips's sniffer accepts), but the internal version field says v7.3/HDF5 (which libmatio, the MATLAB parser libvips uses, honors). This discrepancy lets the attacker bypass libvips's format detection and trigger libmatio to read arbitrary files via HDF5 external storage pointers.
The attack chain: upload crafted .mat payload via direct uploads with content_type: "image/png"; Active Storage treats blob as image and passes to libvips; libvips routes to libmatio, which follows HDF5 external reference to read any file the Rails worker can access (/etc/passwd, config/master.key, /proc/self/environ); file contents returned pixel-by-pixel through thumbnails (1x1 images for byte-exact reads); attacker reads secret_key_base, forges signed variation key, exploits CVE-2025-24293 to achieve instance_eval RCE.
Affected Versions
| Rails Version | Affected | Configuration Required | Patched Version |
|---|---|---|---|
| < 6.0.0 | No | N/A | N/A |
| 6.0.0 - 6.1.7.10 | Yes | Active Storage configured to use Vips (non-default) | 7.2.3.2 |
| 7.0.0 - 7.2.3.1 | Yes | Active Storage enabled (default) | 7.2.3.2 |
| 8.0.0 - 8.0.5 | Yes | Active Storage enabled (default) | 8.0.5.1 |
| 8.1.0 - 8.1.3 | Yes | Active Storage enabled (default) | 8.1.3.1 |
Key insight: Rails 7.0+ uses libvips as the default Active Storage variant processor. The official Rails Docker images install libvips by default on Debian/Ubuntu bases. Most Rails 7+ applications with file uploads are vulnerable in their default configuration.
Applications using ImageMagick (MiniMagick) instead of libvips are not affected by this specific vector.
Impact Assessment
What's at Risk: Arbitrary file read (any file readable by Rails worker), secret disclosure (secret_key_base, master key, credentials, database passwords, cloud keys), remote code execution (via forged variation keys exploiting CVE-2025-24293 on default vips transformer), and lateral movement (disclosed cloud credentials enable pivoting).
Real-World Exposure: GitHub, Shopify, Basecamp, and thousands of self-hosted Rails apps use Active Storage with libvips. The official rails new Dockerfile installs libvips by default. Debian/Ubuntu libvips42 packages link against libmatio13 (1.5.28+). No authentication required for direct upload path. Variation keys are blob-independent and replayable -- a single harvested key from any page works against the attacker's uploaded blob.
Affected Systems
Who Needs to Act Immediately: All Rails 7.0+ applications using Active Storage with file uploads (default); Rails 6.x applications that explicitly configured config.active_storage.variant_processor = :vips; applications deployed via official Rails Docker images or Debian/Ubuntu bases with libvips; any application accepting image uploads from untrusted users.
Mitigation & Patching
Primary Fix: Upgrade Rails
Upgrade to patched versions released July 29, 2026:
The patch calls Vips.block_untrusted(true) when Active Storage initializes, blocking the MATLAB, SVG, FITS, NIfTI, OpenSlide, and Radiance loaders that libvips marks as untrusted.
Note: Rails 7.1 and earlier are end-of-life and will not receive backports. Affected applications on Rails 7.1 or earlier must upgrade to Rails 7.2.3.2 or later.
Immediate Workarounds (If Upgrade Is Delayed)
Option 1: Environment Variable (libvips 8.13+ required) VIPS_BLOCK_UNTRUSTED=1
Option 2: Ruby Initializer (ruby-vips 2.2.1+ required) if defined?(Vips): Vips.block_untrusted(true)
Option 3: Switch to ImageMagick config.active_storage.variant_processor = :mini_magick (requires gem "image_processing" and ImageMagick).
Post-Patch: Rotate All Secrets
After upgrading, rotate every secret the application process could read: generate new master key and re-encrypt credentials; rotate secret_key_base via rails secret; rotate database credentials and server passwords; rotate Active Storage service keys (AWS IAM, GCP service accounts, Azure storage keys); rotate third-party API tokens.
Forensic Analysis
Rails published a forensic toolkit: git clone https://github.com/rails/rails-forensics-CVE-2026-66066 -- searches for MAT v7.3/HDF5 files in Active Storage blobs, variation keys that don't match known transforms, and anomalous file access patterns in logs.
Detection
Indicators of Compromise
- Unexpected MAT/HDF5 files in Active Storage blob storage (check
content_typemismatches) - Anomalous variant generation in logs -- especially 1x1 pixel thumbnails or rapid sequential variant requests
- Variation keys in URLs that don't match your application's declared transforms
- Outbound network connections from image processing worker (RCE chain uses
curlcallbacks) - Modified credentials files or unexpected
rails credentials:editactivity
Log Queries
Network Monitoring
Monitor for outbound connections from Rails application servers to unknown IPs on port 80/443 -- the published PoC uses curl callbacks to exfiltrate data.
Frequently Asked Questions
Is this vulnerability exploitable without authentication?
Yes. The direct upload endpoint (/rails/active_storage/direct_uploads) accepts unauthenticated requests by default.
Does this affect Rails API-only applications?
Only if the API application uses Active Storage and accepts file uploads. API-only apps without Active Storage are not affected.
Can a WAF block this attack?
Limited effectiveness. The payload is a valid HDF5/MAT file that passes libvips's sniffer. WAF rules would need to inspect binary structure of uploaded files, which most WAFs cannot do reliably. GMO Flatt Security concludes WAF mitigation is "extremely limited" and should not replace upgrading.
Are applications using S3/Cloud Storage for Active Storage affected?
Yes. The vulnerability is in variant processing (on your application servers), not in the storage backend. Whether blobs are stored locally, on S3, GCS, or Azure, processing occurs in your Rails workers.
Has this been exploited in the wild?
As of July 30, 2026, the Rails Security Team reports no known exploitation before or after disclosure. However, a public PoC exists on GitHub and Ethiack has published their full chain. The window for safe patching is closing rapidly.
Key Takeaways
-
CVE-2026-66066 (CVSS 9.5) is a critical arbitrary file read to RCE chain in Rails Active Storage when using libvips (default in Rails 7+)
-
Default Rails 7+ configurations are vulnerable -- official Docker images and
rails newsetups install libvips with libmatio support -
The attack requires no authentication and uses standard Active Storage endpoints (direct uploads, variant generation)
-
Upgrade immediately to Rails 7.2.3.2, 8.0.5.1, or 8.1.3.1 -- Rails 7.1 and earlier are EOL and will not receive patches
-
If you cannot upgrade today, set
VIPS_BLOCK_UNTRUSTED=1(requires libvips 8.13+) or callVips.block_untrusted(true)in an initializer (requires ruby-vips 2.2.1+) -
After patching, rotate ALL secrets --
secret_key_base, master key, database credentials, cloud storage keys, API tokens -
Run the Rails forensic toolkit to check for past exploitation in your object storage and database records
-
This vulnerability was discovered with AI assistance (Claude Opus 4.8) -- a sign that AI-accelerated vulnerability research is accelerating disclosure timelines
Conclusion
CVE-2026-66066 demonstrates how a mismatch between two libraries' format detection (libvips sniffing MATLAB 5.0 while libmatio parses HDF5 v7.3) can turn a thumbnail generator into an arbitrary file reader, and how Rails' signed but blob-independent variation keys enable that read to become remote code execution. The fix is straightforward -- enable libvips's existing block_untrusted protection -- but the exposure window is wide because the vulnerable configuration is the default for modern Rails applications.
If you maintain a Rails application with file uploads, treat this as a drop-everything-and-patch event. The PoC is public, the chain is reliable, and the affected surface is the default Rails 7+ stack.
Sources:
- The Hacker News: Critical Rails Flaw Could Let Unauthenticated Attackers Read Server Files via Image Uploads
- Ethiack: KindaRails2Shell -- How a MATLAB file reads your secrets and pops a shell on Ruby on Rails
- GMO Flatt Security: 深刻度「緊急」のRails脆弱性「KindaRails2Shell」(CVE-2026-66066)の概要と対応指針
- Rails Security Advisory: GHSA-xr9x-r78c-5hrm
- Rails Patch Commit: Vips.block_untrusted
- Rails Forensic Toolkit
- Third-Party PoC Repository
- CVE-2025-24293: Active Storage Variant Method Injection
Automated Transmission
This entry was synthesized and populated dynamically using native API integrations.