KindaRails2Shell: Patch Active Storage, Then Rotate Every Secret the App Could Read
CVE-2026-66066 turns an image upload into a file read, and a leaked secret_key_base into code execution.
The Rails team disclosed CVE-2026-66066 on 29 July. It is a critical flaw in Active Storage that lets an unauthenticated attacker upload a crafted image, read arbitrary files from the server, and in many setups reach remote code execution. The advisory scores it 9.5 under CVSS 4.0. The bug was found by Ethiack and GMO Flatt Security, and Akamai has nicknamed it "KindaRails2Shell". BleepingComputer reports that public proof-of-concept exploits appeared quickly, which pushed the full details out early.
Fixed versions are Active Storage 7.2.3.2, 8.0.5.1 and 8.1.3.1. Rails 6.x is affected only if it has been configured away from its defaults.
Who is exposed
You need two conditions: Active Storage uses libvips to process variants, and the app accepts image uploads from people you do not trust. The first has been the default since Rails 7.0. The second covers almost every real app, because avatars, product photos, support attachments and profile banners all count. Apps that use ImageMagick are not affected.
The root cause is that Active Storage did not disable libvips operations that libvips itself marks as unsafe for untrusted input. A crafted upload can make those operations read files from disk, and the process environment is one of them. In a typical Rails deployment that environment holds secret_key_base, database credentials and cloud storage keys.
Why a file read becomes a shell
secret_key_base is the root of most of Rails' integrity guarantees. An attacker who has it can forge session cookies, sign global IDs and tamper with serialised data the app trusts because it is signed. BleepingComputer's write-up describes that chain as leading directly to full RCE. Even without code execution, the database and storage credentials in the environment are enough for a serious breach.
So this is not a patch-and-move-on bug. If a vulnerable app was reachable and accepted uploads, you have to assume the environment may have been read and act on that.
What to do
- Upgrade Rails to a fixed Active Storage release.
- Check the libvips that actually ships in your image. The Rails guidance calls for libvips 8.13 or later. The version comes from your base image's OS packages, not your Gemfile, so run
vips --versioninside the container you deploy and do not assume. - If you cannot upgrade immediately, set the
VIPS_BLOCK_UNTRUSTEDenvironment variable or callVips.block_untrusted(true)with ruby-vips 2.2.1 or later. There is no workaround for libvips older than 8.13. - Rotate secrets:
secret_key_base, database credentials, Active Storage service credentials and anything else in the process environment. Rotatingsecret_key_baseinvalidates existing sessions and signed or encrypted cookies, so plan a forced logout instead of being surprised by one. - Look back through logs for unusual uploads and variant requests since late July, and for use of your cloud and database credentials from unfamiliar addresses.
The longer lesson
Image processing keeps producing the same kind of incident: a capable native library, built for trusted desktop workflows, is put behind a public upload form. CSO's advice is to run image processing in a sandboxed container with minimal filesystem access, and it is the right structural answer. If thumbnailing runs in a worker that has no secret_key_base, no database URL and no network access, the next libvips bug becomes a resource-exhaustion problem and not a breach.
That is more work than bumping a gem, and most teams will not do it this week. But you will want it in place the next time something like this lands. Rails apps that already split processing into a background job are halfway there. The remaining step is to give that job much less of the environment than the web process has.
Sources