Ruby on Rails has patched CVE-2026-66066, a critical Active Storage flaw that can let an unauthenticated attacker read files available to the application process and use exposed secrets for remote code execution or lateral movement. An app is in the confirmed risk path when it uses libvips for Active Storage image processing and accepts image uploads from untrusted users. Upgrade Active Storage to a fixed release, use libvips 8.13 or later, and rotate secrets that the process could read.
The Rails advisory was published on July 29, 2026 with a CVSS 4.0 score of 9.5. Rails released attack details and official forensic tooling on July 31 after researchers published proof-of-concept code earlier than the planned disclosure date. Public PoCs raise urgency, but the project has not said that every Rails app is vulnerable or confirmed a broad exploitation campaign.
Is your Rails application affected?
| Check | What it means |
|---|---|
| Active Storage version | Affected branches are earlier than 7.2.3.2, 8.0 through 8.0.5.0, and 8.1 through 8.1.3.0. Older applications still need a configuration check because the processor choice matters. |
| Variant processor | The confirmed path requires config.active_storage.variant_processor = :vips. Rails apps using ImageMagick instead of libvips are not affected by this specific vector. |
| Who can upload images | The app must accept image content from an untrusted user. A self-service account still counts as untrusted even if registration is required. |
| Active Storage is absent or uploads are fully trusted | The documented chain does not apply, but verify the deployed code and runtime rather than relying on an architecture diagram or old inventory. |
Rails 7 changed the default variant processor to libvips through load_defaults 7.0. A long-lived app can carry forward customized settings, and a container image may supply a different libvips version than a developer laptop. Confirm the deployed Gemfile lock, Rails configuration, image-processing dependency, and upload route together.
How the file read can become code execution
libvips supports many loaders and savers, including operations intended for file types beyond ordinary web images. Some operations are marked unsafe for untrusted content. Active Storage did not block those operations, so a crafted upload could make the image-processing path read another file accessible to the Rails process. The official advisory says an attacker does not need a separate request that explicitly generates a variant.
Files and environment variables available to a Rails process commonly contain secret_key_base, the Rails master key, database credentials, object-storage keys, and third-party service tokens. Reading a file is therefore not the final boundary. A stolen signing or service key can enable forged sessions, access to external systems, or a later route to code execution. This is similar to the practical secret-loss boundary in the Vite arbitrary-file-read vulnerability, although the affected components and request paths are different.
Fixed versions and temporary mitigation
| Branch | Fixed release |
|---|---|
| Rails / Active Storage 7.2 | 7.2.3.2 or later |
| Rails / Active Storage 8.0 | 8.0.5.1 or later |
| Rails / Active Storage 8.1 | 8.1.3.1 or later |
The fixed Active Storage release also requires libvips 8.13 or later. With libvips 8.13+, administrators who cannot immediately update Rails can temporarily set VIPS_BLOCK_UNTRUSTED before libvips initializes. Applications with ruby-vips 2.2.1 or later can call Vips.block_untrusted(true) from an initializer. libvips versions earlier than 8.13 cannot disable the unsafe operations, so removing the dependency or processor is the only documented fallback.
A web application firewall can reduce noisy exploit traffic, but it cannot prove that a crafted file was blocked and it does not revoke a secret that may already have leaked. Treat WAF rules as temporary defense in depth, not as a substitute for the fixed Rails and libvips releases.
Why patching is not enough
The update closes the vulnerable processing path; it cannot make an already copied secret private again. Rails tells affected operators to change every secret the application process could read. That normally includes:
secret_key_baseand the Rails master key;- everything decrypted from
config/credentials.yml.enc; - S3, Google Cloud Storage, Azure, or other Active Storage credentials;
- database usernames and passwords;
- API tokens, webhook secrets, SMTP credentials, and keys for third-party services.
Changing secret_key_base expires active sessions and affects encrypted or signed cookies, signed Global IDs, and signed Active Storage URLs. Plan that user impact, but do not keep the exposed value as a fallback: a fallback keeps the stolen key useful.
How to check for signs of CVE-2026-66066 exploitation
The Rails security team published a dedicated forensic repository with two evidence paths: one determines whether an application was ever vulnerable and over what time window; the other searches Active Storage data for the crafted files and identifies which file was read when evidence exists. The investigation uses records in the application database and object store, not only HTTP access logs.
Finding no crafted file in the available dataset is useful but is not universal proof that no compromise occurred. Retention gaps, deleted objects, replicas, staging deployments, and alternate upload paths can change the evidence. Preserve a snapshot before cleanup, review the official repository and scripts before running them in production, and widen the investigation when a sensitive file was read or a related credential was used.
Response order for an exposed application
- Confirm the deployed exposure. Record the Active Storage version, libvips version, variant processor, upload routes, and the earliest date that all risk conditions were present.
- Preserve evidence. Snapshot relevant databases, object-storage metadata, application logs, deployment records, and current environment configuration before deleting suspicious uploads.
- Patch Active Storage and libvips. Deploy one of the fixed Rails releases with libvips 8.13+ and verify that every production, worker, staging, and review environment received it.
- Rotate reachable secrets. Start with signing keys, master keys, database and storage credentials, then third-party tokens. Remove old values rather than leaving them valid for compatibility.
- Invalidate sessions and signed artifacts. Expect users to sign in again and check whether old signed URLs or cookies remain accepted by any service.
- Run the official forensic checks. Search the database and object store for documented artifacts, then correlate results with access, cloud, database, and identity logs.
- Investigate downstream use. Look for new sessions, unusual database queries, object-storage access, token use, configuration changes, and lateral movement during the exposure window.
- Document the boundary. Separate “was vulnerable,” “artifact found,” “file read,” and “credential used.” These are different evidence states and should not be collapsed into one breach claim.
References
- Rails Security Team. “Possible arbitrary file read and remote code execution in Active Storage variant processing.” Rails project GitHub Security Advisory GHSA-xr9x-r78c-5hrm, published July 29, 2026, accessed August 1, 2026. official advisory.
- Mike Dalessio, Rails Security Team. “[CVE-2026-66066] Attack details, and tools to perform a forensic investigation.” Rails Security Announcements, published July 31, 2026, accessed August 1, 2026. official disclosure and forensic notice.
- Rails Security Team. “rails-forensics-CVE-2026-66066.” GitHub repository, accessed August 1, 2026. official forensic repository.

