Nov 13, 2026·10 min read·2 visits
Active Storage prior to 8.0.5.2 and 8.1.4.1 invokes ImageMagick via MiniMagick without restricting dangerous coders (such as MSL, TEXT, EPHEMERAL, and Ghostscript delegates). Uploading a malicious attachment triggers automatic metadata analysis, enabling unauthenticated arbitrary file read and write on the server.
CVE-2026-122006 is a critical vulnerability in the Ruby on Rails Active Storage framework affecting versions prior to 8.0.5.2 and 8.1.4.1. When an application processes uploaded file attachments using the ImageMagick variant processor (:mini_magick), the framework invokes ImageMagick's metadata analyzer without applying a restrictive security policy. An unauthenticated attacker can upload a crafted file containing directives for unrestricted ImageMagick coders, such as Magick Scripting Language (MSL), resulting in arbitrary server-side file read and write operations. In deployments using the Disk storage service, attackers can exfiltrate sensitive application configuration files, including secret_key_base and master encryption keys, which enables remote code execution via signed payload forgery.
Active Storage is the built-in file upload and attachment management framework in Ruby on Rails. It facilitates uploading files to cloud storage services or local disks and provides an extensible pipeline for extracting metadata and generating image transformations (variants). For image manipulation and analysis, Active Storage supports two primary backend processors: libvips and ImageMagick (interfaced via the mini_magick Ruby gem).
CVE-2026-122006 (also tracked as GHSA-f3w6-w445-fwh9 and CVE-2026-126082) stems from an insecure default initialization (CWE-1188) within Active Storage's ImageMagick integration. When a file is attached to a Rails model, Active Storage automatically queues or executes an analysis job to inspect the file's dimensions and orientation. This analysis occurs automatically upon attachment, even if the application never explicitly requests an image variant or transformation.
Prior to versions 8.0.5.2 and 8.1.4.1, Active Storage invoked ImageMagick subprocesses without supplying a hardened security policy (policy.xml). Consequently, ImageMagick relied entirely on the host operating system's default configuration, which frequently permits non-visual coders and external protocol handlers.
An unauthenticated attacker with access to any file upload endpoint backed by Active Storage can submit a specially crafted file containing embedded ImageMagick coder instructions. During the automatic analysis phase, ImageMagick inspects the file content, selects the corresponding coder, and executes arbitrary file read and write operations on the server filesystem.
The root cause of CVE-2026-122006 lies in how Active Storage initializes MiniMagick::Image during attachment analysis without constraining ImageMagick's coder and delegate subsystems. When config.active_storage.variant_processor is set to :mini_magick (which was the default in Rails versions prior to 7.0, or when load_defaults <= 6.1 is active), Active Storage downloads the uploaded blob to a temporary file and passes its path to MiniMagick:
download_blob_to_tempfile do |file|
image = instrument("mini_magick") do
MiniMagick::Image.new(file.path)
end
# Metadata extraction (width, height, etc.)
endWhen MiniMagick::Image.new executes, it spawns the ImageMagick identify or magick binary against the temporary file. ImageMagick does not rely strictly on the file extension or the HTTP Content-Type header declared during upload; instead, it performs content sniffing (magic byte and structural inspection) to select a format coder.
Without an explicit policy.xml restricting available domains, ImageMagick exposes several high-risk coders and features to untrusted input:
MSL (Magick Scripting Language): An XML-based scripting interpreter built into ImageMagick. If an uploaded file (such as an SVG or XML document) contains MSL syntax, ImageMagick executes <read filename="..." /> and <write filename="..." /> directives, allowing arbitrary file reads and writes under the permissions of the web application process.TEXT and EPHEMERAL Coders: Allow reading arbitrary local files into an image canvas or deleting arbitrary files from the filesystem immediately after reading them.MPC (Magick Pixel Cache): Reads pixel cache data from arbitrary filesystem paths specified inside the uploaded image header.URL, HTTP, HTTPS, FTP, FILE): Enable Server-Side Request Forgery (SSRF) and local file inclusion by fetching external or local resources referenced inside the file.gs, PS, PDF, EPS, etc.): Invoke external interpreter binaries or linked libraries to parse PostScript and PDF files, exposing the application to secondary command injection and memory corruption vulnerabilities.@*): Interprets arguments prefixed with @ by substituting the contents of the referenced file path.The Rails core team remediated CVE-2026-122006 in commits 468aa9a93fc98f5476b6821770f4ccfcb7f7d328 and ea8c40121ce53a3d0255cd4eb6d13bfe3bc01776. The fix introduces a two-part defense: bundling a restrictive policy.xml directly inside the activestorage gem and enforcing its loading via the MAGICK_CONFIGURE_PATH environment variable in MiniMagick.
First, Rails added activestorage/lib/active_storage/image_magick.rb to manage how MiniMagick interacts with the operating system environment. This module prepends Active Storage's internal policy directory to MAGICK_CONFIGURE_PATH using MiniMagick.cli_env, which was introduced in mini_magick version 5.1. If a developer attempts to use :mini_magick with an older version of the mini_magick gem that lacks cli_env=, Active Storage raises a fatal runtime exception during initialization.
module ActiveStorage
module ImageMagick
POLICY_DIRECTORY = File.expand_path("image_magick", __dir__)
def self.apply_policy # :nodoc:
# Preserve any existing operator-configured policy paths
operator_paths = operator_paths(MiniMagick.cli_env["MAGICK_CONFIGURE_PATH"]).presence ||
operator_paths(ENV["MAGICK_CONFIGURE_PATH"])
# Inject Active Storage's policy directory into MiniMagick's CLI environment
MiniMagick.cli_env = MiniMagick.cli_env.merge("MAGICK_CONFIGURE_PATH" => configure_path(operator_paths)).freeze
end
def self.configure_path(operator_path)
[ POLICY_DIRECTORY, *operator_paths(operator_path) ].join(File::PATH_SEPARATOR)
end
def self.operator_paths(path)
Array(path).flat_map { |entry| entry.split(File::PATH_SEPARATOR) } - [ POLICY_DIRECTORY, "" ]
end
private_class_method :operator_paths
end
end
# Enforce mini_magick >= 5.1 so cli_env is guaranteed to be supported
ActiveStorage::MINIMAGICK_UNSECURABLE = ActiveStorage::MINIMAGICK_AVAILABLE && !MiniMagick.respond_to?(:cli_env=)
module ActiveStorage
def self.require_securable_mini_magick! # :nodoc:
if MINIMAGICK_UNSECURABLE
raise <<~ERROR.squish
Active Storage's ImageMagick security policy requires mini_magick 5.1 or later. Please add
`gem "mini_magick", "~> 5.1"` to your Gemfile, or use the :vips variant processor.
ERROR
end
end
endSecond, the patch ships activestorage/lib/active_storage/image_magick/policy.xml, which is applied alongside any existing host-level policy.xml. Because ImageMagick 6 and ImageMagick 7 have different support for the module domain, the shipped policy explicitly uses the coder, delegate, and path domains, which both major versions enforce consistently. Furthermore, because multiple coder tokens map to the same underlying Ghostscript parser, every individual token alias is explicitly denied:
<policymap>
<!-- Deny Magick Scripting Language -->
<policy domain="coder" rights="none" pattern="MSL"/>
<!-- Deny file-reading and file-deleting coders -->
<policy domain="coder" rights="none" pattern="EPHEMERAL"/>
<policy domain="coder" rights="none" pattern="TEXT"/>
<policy domain="coder" rights="none" pattern="MPC"/>
<!-- Deny screen display coders -->
<policy domain="coder" rights="none" pattern="SHOW"/>
<policy domain="coder" rights="none" pattern="WIN"/>
<policy domain="coder" rights="none" pattern="PLT"/>
<!-- Deny remote and local URL/file reference coders -->
<policy domain="coder" rights="none" pattern="URL"/>
<policy domain="coder" rights="none" pattern="HTTP"/>
<policy domain="coder" rights="none" pattern="HTTPS"/>
<policy domain="coder" rights="none" pattern="FTP"/>
<policy domain="coder" rights="none" pattern="FILE"/>
<!-- Deny Ghostscript delegate and all associated coder tokens -->
<policy domain="delegate" rights="none" pattern="gs"/>
<policy domain="coder" rights="none" pattern="PS"/>
<policy domain="coder" rights="none" pattern="PS2"/>
<policy domain="coder" rights="none" pattern="PS3"/>
<policy domain="coder" rights="none" pattern="EPS"/>
<policy domain="coder" rights="none" pattern="EPS2"/>
<policy domain="coder" rights="none" pattern="EPS3"/>
<policy domain="coder" rights="none" pattern="EPI"/>
<policy domain="coder" rights="none" pattern="EPSF"/>
<policy domain="coder" rights="none" pattern="EPSI"/>
<policy domain="coder" rights="none" pattern="EPT"/>
<policy domain="coder" rights="none" pattern="EPT2"/>
<policy domain="coder" rights="none" pattern="EPT3"/>
<policy domain="coder" rights="none" pattern="PDF"/>
<policy domain="coder" rights="none" pattern="AI"/>
<policy domain="coder" rights="none" pattern="EPDF"/>
<policy domain="coder" rights="none" pattern="PDFA"/>
<policy domain="coder" rights="none" pattern="POCKETMOD"/>
<policy domain="coder" rights="none" pattern="XPS"/>
<policy domain="coder" rights="none" pattern="PCL"/>
<!-- Deny @filename argument substitution -->
<policy domain="path" rights="none" pattern="@*"/>
</policymap>> [!NOTE]
> The comments in the official patch highlight a critical nuance in ImageMagick's XML tokenizer: placing a backtick (`) anywhere in policy.xml causes the tokenizer to treat it as an opening quote, silently dropping every policy rule up to the next apostrophe. The shipped file strictly avoids backticks to prevent policy bypasses.
Exploiting CVE-2026-122006 requires three prerequisites: the target Rails application must have Active Storage configured to use :mini_magick, the application must expose a file upload endpoint, and the host operating system must lack an existing policy.xml that blocks the MSL or TEXT coders.
To execute an arbitrary file write or read, an attacker crafts an XML payload using Magick Scripting Language (MSL) directives. Even if the application validates the filename extension (e.g., requiring .svg or .png), ImageMagick inspects the payload body and invokes the MSL interpreter if XML <image> tags are present:
<?xml version="1.0" encoding="UTF-8"?>
<image>
<read filename="/app/config/credentials/production.key" />
<write filename="/app/storage/public_exfiltrate.png" />
</image>When this file is submitted via an HTTP POST request to an Active Storage upload endpoint, Active Storage saves the blob and invokes ActiveStorage::Analyzer::ImageAnalyzer::ImageMagick. The analyzer runs MiniMagick::Image.new(file.path) to determine the image's width and height. At this stage, before any custom application controller logic or post-processing runs, ImageMagick executes the <read> and <write> commands embedded in the file.
If the application uses the Active Storage Disk service (config.active_storage.service = :local), uploaded blobs are stored directly on the local server filesystem in a structured directory hierarchy (storage/xx/yy/xxyy...). An attacker can upload a normal file to obtain its blob key or predictable storage path, and then upload an MSL payload that reads a sensitive target file (such as /app/config/master.key, /app/config/credentials.yml.enc, or /proc/self/environ) and overwrites the previously uploaded blob on disk. When the attacker subsequently downloads their first attachment via its standard Active Storage URL, the server returns the exfiltrated secret file.
CVE-2026-122006 carries a CVSS v3.1 base score of 9.8 (Critical) with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H. The attack requires no privileges (PR:N), no user interaction (UI:N), and exhibits low attack complexity (AC:L) over the network (AV:N).
In any vulnerable configuration (regardless of whether blobs are stored on local disk or in cloud storage such as Amazon S3), an attacker achieves arbitrary file write capabilities on the application server. By writing files to /app/views/, /app/controllers/, or config/initializers/, or by overwriting existing application source code writable by the Ruby process, an attacker can achieve direct Remote Code Execution (RCE). Furthermore, the EPHEMERAL coder allows an attacker to delete arbitrary files writable by the web user, causing denial of service.
When the application is configured to use the Active Storage Disk service, the impact expands to reliable arbitrary file read. By reading /proc/self/environ, config/master.key, or config/credentials.yml.enc, an attacker can extract the application's secret_key_base as well as database credentials and third-party API tokens.
In Ruby on Rails, compromising secret_key_base allows an attacker to forge valid ActiveSupport::MessageVerifier and ActiveSupport::MessageEncryptor payloads. Depending on the session storage configuration and deserialization primitives in use (such as Marshal-serialized cookies or signed Active Storage blob IDs), forging tokens with a known secret_key_base escalates directly to unauthenticated Remote Code Execution.
As of November 2026, the EPSS score for CVE-2026-122006 is 0.00741 (55.14th percentile), and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. A community auditing and detection script (cve-2026-122006-check) has been published on GitHub to help administrators identify vulnerable Gemfile.lock states and unhardened host ImageMagick policies.
The primary remediation is to upgrade the activestorage gem to version 8.0.5.2 (for the Rails 8.0 release series) or 8.1.4.1 (for the Rails 8.1 release series). Because the security fix relies on MiniMagick.cli_env to inject MAGICK_CONFIGURE_PATH, applications using the :mini_magick processor must also upgrade the mini_magick gem to version 5.1 or later:
bundle update activestorage mini_magick> [!NOTE]
> If your application transforms PDF or PostScript files through Active Storage using ImageMagick, upgrading to the patched versions will block those transformations by default because the gs delegate and PDF/PS coders are denied. Operators who explicitly require PDF processing must re-enable those coders in their host-level policy.xml, which takes precedence when configured appropriately.
For environments that cannot immediately upgrade Rails or activestorage, two effective workarounds are available:
Switch Variant Processor to libvips: Migrate away from ImageMagick by configuring Active Storage to use :vips in config/application.rb or the environment configuration files (config/environments/production.rb). Note that libvips has been the default processor for new Rails applications since Rails 7.0:
config.active_storage.variant_processor = :vipsDeploy a Host-Level ImageMagick Security Policy: Apply the restrictive <policymap> rules directly to the system-wide ImageMagick configuration file (typically located at /etc/ImageMagick-6/policy.xml or /etc/ImageMagick-7/policy.xml). After updating the host policy, verify that the restrictions are active within the Rails runtime environment:
bin/rails runner 'puts MiniMagick.identify { |i| i.list "policy" }'If an application was running a vulnerable version of Active Storage with the :mini_magick processor and the Disk storage service while exposed to untrusted uploads, operators must assume that filesystem secrets may have been read. Incident response teams should rotate secret_key_base, regenerate config/master.key and config/credentials.yml.enc, rotate database and cloud API credentials, and invalidate all existing user sessions.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
activestorage Ruby on Rails | < 8.0.5.2 | 8.0.5.2 |
activestorage Ruby on Rails | >= 8.1.0, < 8.1.4.1 | 8.1.4.1 |
| Attribute | Detail |
|---|---|
| CVE ID | CVE-2026-122006 (GHSA-f3w6-w445-fwh9) |
| Weakness Class | CWE-1188 (Initialization of a Resource with an Insecure Default) |
| Attack Vector | Network (Unauthenticated File Upload) |
| CVSS v3.1 Score | 9.8 CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| EPSS Score | 0.74% (55.14th Percentile) |
| Primary Impact | Arbitrary File Read & Write / Secret Exfiltration / RCE |
| Exploit Status | Proof-of-Concept & Detection Tooling Available |
| CISA KEV Status | Not Listed |
The software initializes or sets up a resource with a default configuration that is insecure, leaving the application open to abuse or compromise if the defaults are not hardened by the operator.
CVE-2026-126190 (GHSA-mmhr-3c5m-f64f) is an inefficient algorithmic complexity vulnerability (CWE-407) in Soup Sieve, the default CSS selector library integrated into Beautiful Soup 4. In versions prior to 4.0, evaluating CSS selectors that contain descendant combinators (whitespace between compound selectors) executes an unmemoized upward traversal of the document tree. When evaluated against deeply nested HTML or XML documents, the time complexity scales polynomially at O(n^(k+1)), where n is the tree depth and k is the number of descendant combinators. Remote attackers can supply compact, deeply nested markup (1 KB to 4 KB) to trigger prolonged CPU starvation and denial of service in Python applications.
CVE-2026-128065 (also tracked as GHSA-gg5j-6742-v827) is an authorization bypass vulnerability affecting the @grpc/grpc-js-xds library in the Node.js gRPC ecosystem. In versions 1.14.0 and 1.14.1, XdsServer acknowledges Route and VirtualHost resources from an xDS control plane while failing to parse, store, or apply RBACPerRoute override configurations. When experimental RBAC is enabled and a broad top-level ALLOW policy is paired with restrictive VirtualHost or Route overrides, the server evaluates requests strictly against the top-level policy, permitting unauthorized RPC execution.
CVE-2026-126188 (GHSA-3f4q-8x5m-76v8) is an information disclosure vulnerability in the Active Storage component of Ruby on Rails prior to versions 8.0.5.2 and 8.1.4.1. When generating previews or extracting metadata from uploaded media files, Active Storage invokes the external command-line tools ffmpeg and ffprobe without specifying a format whitelist. An attacker who can upload a crafted HTTP Live Streaming (HLS) playlist while declaring a standard video or audio MIME type can cause FFmpeg to engage the HLS demuxer, resolve file:// segment URIs, and disclose visual frames or metadata from local media files readable by the Rails application process.
CVE-2026-126206 (GHSA-jcff-cj73-4w4f) is a Cross-Site Scripting (XSS) vulnerability in version 2.25.2 of the Loofah Ruby gem. The vulnerability stems from an incomplete character reference normalization routine in the `Loofah::HTML5::Scrub.allowed_uri?` method, which fails to decode the HTML5 named character reference `/` (representing the solidus character `/`). Consequently, a crafted `data:` URI such as `data:text/html,<script>alert(1)</script>` bypasses mediatype validation by triggering the WHATWG MIME parser fallback to `text/plain`, while web browsers later resolve `/` to `/` and execute the payload as `text/html`.
pgEdge RAG Server versions prior to 2.0.0 contain a race condition in the hybrid search pipeline orchestrator (CWE-362, CWE-488). The server maintains a single shared, in-memory BM25 index instance across all incoming HTTP requests on a pipeline. Concurrent queries to the unauthenticated HTTP REST API interleave non-atomic clear, document addition, and search operations on this singleton index. As a result, documents fetched using one caller's search filter can be queried and returned to another concurrent caller, bypassing multi-tenant data isolation without generating any anomalous audit trail in server or database logs.
CVE-2026-118740 is a Missing Authorization (CWE-862) vulnerability in the Microsoft Aspire Dashboard and Aspire.Dashboard.Sdk.linux-x64 packages. In versions 13.6.1 prior to 13.6.5, an architectural flaw in the Blazor routing configuration (Routes.razor) causes unmapped (404 / Not-Found) routes to bypass the AuthorizeRouteView component. By navigating to an arbitrary non-existent route, an unauthenticated remote attacker forces the application into the NotFound template, which unconditionally renders the primary MainLayout component and initializes global user interface services, interaction providers, and underlying SignalR/Blazor circuits without verifying authentication credentials.