A critical flaw in Ruby on Rails lets an unauthenticated attacker read arbitrary files from an application server by uploading a crafted image. It carries a CVSSv4 score of 9.5, and the researchers who documented it have named it KindaRails2Shell.
The advisory went out on 29 July. Full technical details followed on 31 July, four weeks ahead of the schedule originally set.
What the flaw is
Active Storage passes uploaded attachments to an image analyser and transformer. Where libvips is the processing library, it did not block unsafe operations before handing the file over. A crafted upload can therefore invoke one of those operations and return the contents of files the Rails worker process can read.
Whether an application is exposed depends on its image backend. Only deployments using libvips for Active Storage are affected. While this makes it a configuration issue rather than a blanket Rails flaw, libvips is a common choice for a function — user image uploads — that is often exposed to the internet.
Affected and fixed versions
| Branch | Affected range | Fixed in |
|---|---|---|
| Rails 7.x | 7.0.0 – 7.2.3.1 | 7.2.3.2 |
| Rails 8.0.x | 8.0.0 – 8.0.5 | 8.0.5.1 |
| Rails 8.1.x | 8.1.0 – 8.1.3 | 8.1.3.1 |
| Rails 6.0 – 6.1 | Affected where Active Storage uses Vips | No supported fix — these branches are out of support |
Version ranges as published in the advisory. The 6.x branches are named as affected under the same configuration but are no longer supported, so there is no patched release for them; those deployments need a workaround or an upgrade.
The part that will catch people: patching Rails is not enough
The fix works by disabling untrusted operations during Active Storage initialisation, but that capability lives in the image library, not in Rails. It only functions if the underlying libvips is new enough to support it.
Rapid7's advisory is plain: updating Rails or Active Storage alone is not sufficient if an older version of libvips is installed. The requirement is libvips 8.13 or later, together with ruby-vips 2.2.1 or later.
| What you have | What happens |
|---|---|
| Patched Rails, libvips 8.13+, ruby-vips 2.2.1+ | Protected — untrusted operations are blocked at boot |
| Patched Rails, older libvips or ruby-vips | The application refuses to start, by design |
| Unpatched Rails, libvips in use | Exposed |
| Any Rails, a non-libvips image processor | Not affected by this issue |
Behaviour as described in the advisory. The refusal to boot is deliberate: rather than starting in a state where the protection silently does nothing, the patched releases fail closed. Teams that upgrade Rails without checking their system libvips should expect a deployment to stop rather than a vulnerability to persist quietly.
Failing closed is the right call, and it will still be a surprise on a Friday deploy. The dependency being checked is a system library, not a gem, so it is the one least likely to be pinned in the same place as the rest of the stack.
Why a file read scores 9.5
Arbitrary file read sounds like an information-disclosure issue. It scores as critical here because of what those files contain in a Rails application.
| What can be read | What it unlocks |
|---|---|
| secret_key_base and signing material | Forged signed values, which is the documented route from file read toward code execution |
| The Rails master key | Decryption of encrypted credentials, and everything inside them |
| Database credentials | Direct access to application data |
| Storage service credentials | Read and write access to object storage |
| Third-party service tokens | Lateral movement into other systems |
Escalation paths as described in the advisory. The researchers note that recovering Rails signing material allows an ImageProcessing 1.x variation to be forged, and that this route does not require Marshal deserialization. We have deliberately kept the description at this level.
That chain is why the naming convention matters. A bug that reads one file is a problem; a bug that reads the file holding every other secret is a foothold.
What to do
Upgrade to 7.2.3.2, 8.0.5.1 or 8.1.3.1, and check the system libvips at the same time rather than afterwards.
If you cannot upgrade immediately, the advisory offers two temporary measures for deployments already on libvips 8.13 or later. You can either set the VIPS_BLOCK_UNTRUSTED environment variable or call Vips.block_untrusted(true) from an initialiser, which requires ruby-vips 2.2.1 or later. For anything older than libvips 8.13, the advisory is blunt — the only workaround is to remove the libvips dependency.
Rails has also published forensic tooling alongside the patch, which is worth running rather than assuming the window was clean.
How to tell whether you were reached
A successful attack reads files without writing them, leaving no obvious damage. Nothing crashes, nothing is defaced, and the application keeps serving as normal.
The Rails team also published forensic tooling; run it instead of assuming the exposure window was quiet. The place to look is the upload path, for any images that were accepted but then failed transformation in an unusual way.
If you find evidence of secret exposure, the response has another half. If there is reason to believe files were read, rotating secret_key_base, the master key, database credentials and storage tokens is the remediation — patching closes the door, it does not invalidate anything that already went out through it.
Where exploitation stands
As of 30 July, Rapid7 said it was not aware of exploitation in the wild. Proof-of-concept code emerged subsequently, and the full technical write-up was published on 31 July rather than the originally planned 28 August.
The practical risk is that compressed timeline. On comparable issues, the gap between a public proof of concept and the start of opportunistic scanning has been hours, not weeks — we reported last week on a SharePoint flaw exploited within hours of its PoC appearing, in a wave where patching alone also turned out to be insufficient.
The caveats
- Exposure depends on configuration. This affects applications using libvips for Active Storage image processing, not every Rails deployment.
- No confirmed in-the-wild exploitation had been reported at the time of the advisory. That is a point-in-time statement, not an assurance.
- We have withheld operational detail. The mechanics of the unsafe operation are in the vendor research for defenders who need them to write detections.
- The 6.x branches have no patched release. Anything on them needs the workaround or an upgrade path, not a version bump.
- CVSS measures severity, not your exposure. A 9.5 on an internal application behind authentication is a different operational problem from a 9.5 on a public upload endpoint.
Key takeaways
- CVE-2026-66066 scores 9.5 and needs no authentication beyond the ability to upload an image.
- Fixed in Rails 7.2.3.2, 8.0.5.1 and 8.1.3.1; the 6.x branches have no patched release.
- The fix requires libvips 8.13+ and ruby-vips 2.2.1+ — patching Rails alone does not close it.
- Patched releases refuse to boot if the underlying image library is too old to support the protection.
- File read escalates through secret_key_base, which explains the critical score.