CVE-2026-33173 Overview
A security vulnerability exists in Ruby on Rails Active Storage that allows attackers to bypass content-type validation during direct file uploads. The DirectUploadsController accepts arbitrary metadata from the client and persists it on the blob without proper filtering. Because internal flags like identified and analyzed are stored in the same metadata hash, a malicious client can manipulate these flags to skip MIME detection and analysis, enabling the upload of arbitrary content while claiming a safe content_type.
Critical Impact
Attackers can upload malicious files (such as executable scripts or malware) while bypassing Active Storage's automatic content type identification, potentially leading to stored XSS, server-side code execution, or distribution of malicious content through trusted Rails applications.
Affected Products
- Ruby on Rails versions prior to 8.1.2.1
- Ruby on Rails versions prior to 8.0.4.1
- Ruby on Rails versions prior to 7.2.3.1
Discovery Timeline
- 2026-03-24 - CVE CVE-2026-33173 published to NVD
- 2026-03-24 - Last updated in NVD database
Technical Details for CVE-2026-33173
Vulnerability Analysis
This vulnerability stems from improper input validation in the Active Storage component of Ruby on Rails (CWE-925). The DirectUploadsController is designed to handle file uploads directly to cloud storage services, but it fails to filter user-supplied metadata before persisting it to the blob record.
The core issue is that Active Storage stores both user-controllable metadata and internal processing flags (analyzed, identified, composed) within the same metadata hash. When a direct-upload client submits a request with these internal flags pre-set, the application accepts them without validation, effectively telling the system that content-type analysis has already been performed.
This design flaw allows attackers to bypass any server-side validations that rely on Active Storage's automatic content type identification. For example, an attacker could upload a malicious HTML file containing JavaScript while declaring it as image/png, and the validation bypass would prevent the server from correctly identifying the true content type.
Root Cause
The root cause is the lack of separation between user-supplied metadata and internal system flags in the Active Storage blob metadata hash. The DirectUploadsController accepted all metadata parameters from the client without filtering protected internal properties. This architectural oversight allowed external manipulation of internal state flags that should only be set by the server-side analysis process.
Attack Vector
The attack is network-based and requires no authentication or special privileges. An attacker with knowledge of this vulnerability can craft HTTP requests to the direct upload endpoint with manipulated metadata parameters. By including identified: true and analyzed: true in the upload metadata, the attacker instructs Active Storage to skip its content-type detection routines.
The attack flow involves:
- Initiating a direct upload request to the Rails application
- Including malicious metadata flags (identified, analyzed, composed) set to true
- Specifying a benign content_type (e.g., image/png) while uploading malicious content
- The server accepts the upload without performing actual MIME detection
- The malicious file is stored with the attacker-specified content type
# Security patch in activestorage/app/models/active_storage/blob.rb
# Source: https://github.com/rails/rails/commit/707c0f1f41f067fdf96d54e99d43b28dfaae7e53
MINIMUM_TOKEN_LENGTH = 28
has_secure_token :key, length: MINIMUM_TOKEN_LENGTH
+
+ # FIXME: these property should never have been stored in the metadata.
+ # The blob table should be migrated to have dedicated columns for theses.
+ PROTECTED_METADATA = %w(analyzed identified composed)
+ private_constant :PROTECTED_METADATA
store :metadata, accessors: [ :analyzed, :identified, :composed ], coder: ActiveRecord::Coders::JSON
class_attribute :services, default: {}
Detection Methods for CVE-2026-33173
Indicators of Compromise
- Direct upload requests containing identified, analyzed, or composed parameters in the metadata payload
- Files stored with mismatched content types (e.g., executable content stored as images)
- Unusual patterns in Active Storage blob metadata showing pre-set analysis flags
- Upload requests with suspicious content-type declarations that don't match file signatures
Detection Strategies
- Monitor direct upload endpoint (/rails/active_storage/direct_uploads) for requests containing protected metadata fields
- Implement web application firewall rules to flag requests with identified, analyzed, or composed in JSON payloads
- Audit existing Active Storage blobs for files where identified: true exists without corresponding analysis timestamps
- Review application logs for direct upload requests with abnormal metadata structures
Monitoring Recommendations
- Enable detailed logging for the DirectUploadsController to capture all incoming metadata parameters
- Set up alerts for file uploads where declared content-type doesn't match actual file signature analysis
- Monitor for increased direct upload activity that may indicate exploitation attempts
- Implement integrity monitoring on stored files to detect content-type mismatches
How to Mitigate CVE-2026-33173
Immediate Actions Required
- Upgrade Ruby on Rails to version 8.1.2.1, 8.0.4.1, or 7.2.3.1 immediately
- Review existing Active Storage blobs for potentially malicious uploads with pre-set analysis flags
- Consider temporarily disabling direct uploads if immediate patching is not possible
- Implement additional server-side content-type validation independent of Active Storage's built-in detection
Patch Information
The Rails team has released security patches across all supported versions. The fix introduces a PROTECTED_METADATA constant that explicitly defines the internal metadata fields (analyzed, identified, composed) and filters them from user-supplied input in the DirectUploadsController.
Patched versions:
For detailed technical information, refer to the GitHub Security Advisory GHSA-qcfx-2mfw-w4cg.
Workarounds
- Implement a custom controller that filters protected metadata fields before passing to Active Storage
- Add application-level middleware to strip identified, analyzed, and composed parameters from direct upload requests
- Deploy content-type verification at the storage layer (e.g., S3 Lambda triggers) to validate files after upload
- Temporarily restrict direct uploads to authenticated users with additional validation
# Workaround: Custom DirectUploadsController with metadata filtering
class SecureDirectUploadsController < ActiveStorage::DirectUploadsController
private
def blob_args
params.require(:blob).permit(:filename, :byte_size, :checksum, :content_type, metadata: {}).tap do |args|
# Filter protected metadata fields
if args[:metadata]
args[:metadata] = args[:metadata].except('analyzed', 'identified', 'composed')
end
end
end
end
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


