Ruby on Rails disclosed a critical Active Storage flaw that can let an unauthenticated attacker read arbitrary files from a Rails server through a crafted image upload. The vulnerable path can expose the application process environment, where deployments commonly keep secret_key_base, storage credentials, database passwords, and tokens for other services.
CVE-2026-66066 affects applications that use libvips for Active Storage image processing and accept images from untrusted users. Rails rated it 9.5 under CVSS v4. The maintainers say exposed process credentials can support remote code execution or lateral movement, but neither the advisory nor the researchers’ public reports establish exploitation in the wild.
Active Storage passed untrusted content to operations built for more than images
Active Storage uses libvips to build image variants such as avatars and thumbnails. libvips, in turn, reads and writes formats through loaders, savers, and other operations supplied by its own code and linked third-party libraries. Some are marked unfuzzed because they are not considered safe for untrusted content. Several handle formats unrelated to ordinary web images.
Before the fix, Active Storage did not disable those unfuzzed operations. Rails says an attacker who can upload a crafted file can cause libvips to invoke one of them and disclose a file that the application process can read. The advisory also says variant generation is not a separate exposure condition, so an inventory limited to routes that explicitly request thumbnails can miss an affected upload path.
Ethiack’s coordinated disclosure narrows the deployment conditions. The application must use the vips processor, accept untrusted image uploads, and run a libvips build linked against certain third-party libraries. Common Rails 7.x and 8.x configurations can meet those conditions. Rails 6.x requires a non-default Active Storage setup. Applications using ImageMagick rather than libvips are not affected by this vector.

Figure details
An untrusted user sends a crafted image to a Rails application that accepts uploads. Active Storage passes the file into its vips variant processor. Before the fix, that processor could invoke a libvips operation marked unfuzzed. The operation could read files and environment values available to the Rails process, including secret_key_base, the Rails master key, storage credentials, database credentials, and third-party tokens. Those secrets can affect Rails sessions and signed data or provide identities for storage, database, cloud, and other connected systems. The fixed Active Storage releases disable unfuzzed operations and require libvips 8.13 or later. Secret replacement is still required because the update cannot invalidate material already disclosed.
On August 23, Ethiack published the previously withheld chain after proof-of-concept code began appearing and Rails released forensic tooling. The researchers describe a crafted MATLAB/HDF5 file that makes libvips and libmatio read an external file, while Active Storage’s direct-upload path accepts an attacker-declared image content type. A reusable variation key can then turn generated thumbnails into a file-read oracle. Rails’ advisory itself still omits the chain and points to an August 28 disclosure deadline.
Defenders can now look for direct-upload metadata that claims image/png while the stored bytes begin with MATLAB 5.0 and carry the MAT v7.3 version word 0x0200. Other staging signals include repeated 1-by-1 variant requests against a newly uploaded blob and a variation key reused across different blob IDs. Those traces establish attempted or completed processing, so correlate them with generated variants, file access, and use of the application’s credentials before assigning impact.
The patch closes the operation, not the credential exposure
Fixed Active Storage versions are 7.2.3.2, 8.0.5.1, and 8.1.3.1. The update disables the unsafe libvips operations before processing untrusted content. It also requires libvips 8.13 or later because older builds cannot block those operations. An affected application can therefore fail to boot after the Rails update until the underlying library is upgraded.
For libvips 8.13 or later, VIPS_BLOCK_UNTRUSTED is a temporary control when an immediate Rails upgrade is impossible. Applications using ruby-vips 2.2.1 or later can call Vips.block_untrusted(true) during initialization. Ethiack says a WAF may reduce exposure in some architectures but is not a fix.
GMO Flatt Security, which independently found the flaw, describes remote code execution as possible in common affected configurations rather than inevitable in every Rails deployment. The distinction matters. File disclosure is the directly documented capability. Remote execution depends on what the process can read and how those secrets authorize Rails or connected systems.
The update cannot recover a credential that already left the server. Rails tells affected operators to replace secret_key_base; the Rails master key and every value it decrypts; Active Storage keys for S3, Google Cloud Storage, or Azure; database credentials; and tokens for third-party services. Rotation is only an intermediate step when an old value remains valid as a fallback.
Changing secret_key_base expires active sessions and changes encrypted or signed cookies, signed global IDs, and Active Storage URLs. That disruption is evidence that the old signing material is no longer accepted, not an incidental side effect to avoid.
Prove both the code path and every exposed identity changed
First, inventory the deployed activestorage version, config.active_storage.variant_processor, the system libvips version, and every route or background job that accepts or processes an image from an untrusted user. Confirm production runs 7.2.3.2, 8.0.5.1, 8.1.3.1, or later and libvips 8.13 or later. Restart each web and worker process and capture successful boot evidence. If a temporary block is used, verify VIPS_BLOCK_UNTRUSTED or Vips.block_untrusted(true) is active in every process class, not only the web tier.
Second, build a credential inventory from the actual process environment, config/master.key, RAILS_MASTER_KEY, config/credentials.yml.enc, Active Storage service configuration, database configuration, and service clients. Replace every reachable secret at its issuing system, remove the old value rather than retaining it as fallback, and verify the old credential fails. Expire existing Rails sessions and signed artifacts tied to the previous secret_key_base.
Review upload, request, worker, storage, cloud, database, and identity-provider records from the earliest untrusted-image exposure through credential replacement. Look for unusual image uploads followed by variant-processing errors, repeated small variant requests, reads or requests outside normal image paths, new storage or database sessions, and third-party access using the application’s identities. The published mechanics improve recognition, but incomplete file-read and service-side telemetry remains a material blind spot.
Run one final production check after restarts and credential replacement: each affected upload path reports a fixed Active Storage release and libvips 8.13 or later, and every retired credential fails authentication. The expected result is no unsafe processor, no accepted old secret, and reconciled downstream access through the replacement time; gaps in upload history or service-side authentication records remain documented uncertainty.
