CVE-2024-54133
Description
Action Pack is a framework for handling and responding to web requests. There is a possible Cross Site Scripting (XSS) vulnerability in the content_security_policy helper starting in version 5.2.0 of Action Pack and prior to versions 7.0.8.7, 7.1.5.1, 7.2.2.1, and 8.0.0.1. Applications which set Content-Security-Policy (CSP) headers dynamically from untrusted user input may be vulnerable to carefully crafted inputs being able to inject new directives into the CSP. This could lead to a bypass of the CSP and its protection against XSS and other attacks. Versions 7.0.8.7, 7.1.5.1, 7.2.2.1, and 8.0.0.1 contain a fix. As a workaround, applications can avoid setting CSP headers dynamically from untrusted input, or can validate/sanitize that input.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Action Pack's content_security_policy helper before 7.0.8.7, 7.1.5.1, 7.2.2.1, 8.0.0.1 lacks input validation, allowing CSP injection via untrusted input.
Vulnerability
CVE-2024-54133 is a low-severity Cross-Site Scripting (XSS) vulnerability in the content_security_policy helper of Ruby on Rails' Action Pack framework, introduced in version 5.2.0 and fixed in versions 7.0.8.7, 7.1.5.1, 7.2.2.1, and 8.0.0.1 [1]. The root cause is insufficient input validation when building CSP directive values; the helper does not reject inputs containing semicolons or whitespace, which are the delimiters used to separate directives and values within a CSP header [4].
Exploitation
An application is vulnerable only if it dynamically sets CSP headers based on untrusted user input, such as parameters or data from external sources [1]. An attacker can inject arbitrary CSP directives by crafting a string that includes characters like ; or whitespace, which are normally used to separate directives in the CSP policy. For example, a malicious input could append script-src 'unsafe-inline' to bypass the intended policy. No authentication is required to exploit this; the attack surface is any endpoint that reflects user input into the CSP header.
Impact
Successful exploitation allows an attacker to modify the Content-Security-Policy header, potentially disabling or weakening security restrictions. This can lead to bypassing the CSP's protection against XSS and other injection attacks, enabling the attacker to execute arbitrary scripts in the context of the victim's browser [1].
Mitigation
Rails has released patched versions that add validation logic to raise an InvalidDirectiveError when a directive value contains semicolons or whitespace [4]. As a workaround, applications should avoid setting CSP headers from untrusted input, or carefully sanitize and validate any such input to ensure it does not contain CSP delimiters [1].
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
actionpackRubyGems | >= 5.2.0, < 7.0.8.7 | 7.0.8.7 |
actionpackRubyGems | >= 7.1.0, < 7.1.5.1 | 7.1.5.1 |
actionpackRubyGems | >= 7.2.0, < 7.2.2.1 | 7.2.2.1 |
actionpackRubyGems | >= 8.0.0, < 8.0.0.1 | 8.0.0.1 |
Affected products
17- Range: v7.1.0, v7.1.1, v7.1.2, …
- Range: >=5.2.0, <7.0.8.7 and >=7.1.0, <7.1.5.1 and >=7.2.0, <7.2.2.1 and >=8.0.0, <8.0.0.1
- osv-coords15 versionspkg:bitnami/railspkg:gem/actionpackpkg:rpm/opensuse/rubygem-actioncable-8.0&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/rubygem-actionmailbox-8.0&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/rubygem-actionmailer-8.0&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/rubygem-actionpack-8.0&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/rubygem-actiontext-8.0&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/rubygem-actionview-8.0&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/rubygem-activejob-8.0&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/rubygem-activemodel-8.0&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/rubygem-activerecord-8.0&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/rubygem-activestorage-8.0&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/rubygem-activesupport-8.0&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/rubygem-rails-8.0&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/rubygem-railties-8.0&distro=openSUSE%20Tumbleweed
>= 5.2.0, < 7.0.9+ 14 more
- (no CPE)range: >= 5.2.0, < 7.0.9
- (no CPE)range: >= 5.2.0, < 7.0.8.7
- (no CPE)range: < 8.0.1-1.1
- (no CPE)range: < 8.0.1-1.1
- (no CPE)range: < 8.0.1-1.1
- (no CPE)range: < 8.0.1-1.1
- (no CPE)range: < 8.0.1-1.1
- (no CPE)range: < 8.0.1-1.1
- (no CPE)range: < 8.0.1-1.1
- (no CPE)range: < 8.0.1-1.1
- (no CPE)range: < 8.0.1-1.1
- (no CPE)range: < 8.0.1-1.1
- (no CPE)range: < 8.0.1-1.1
- (no CPE)range: < 8.0.1-1.1
- (no CPE)range: < 8.0.1-1.1
Patches
8778eab82653814c115b120ed33beb0a38db1a993c27a50395558e72f22fcAdd CSP directive validation
3 files changed · +56 −4
actionpack/CHANGELOG.md+8 −0 modified@@ -1,3 +1,11 @@ +* Add validation to content security policies to disallow spaces and semicolons. + Developers should use multiple arguments, and different directive methods instead. + + [CVE-2024-54133] + + *Gannon McGibbon* + + ## Rails 7.1.5 (October 30, 2024) ## * No changes.
actionpack/lib/action_dispatch/http/content_security_policy.rb+21 −4 modified@@ -24,6 +24,9 @@ module ActionDispatch # :nodoc: # policy.report_uri "/csp-violation-report-endpoint" # end class ContentSecurityPolicy + class InvalidDirectiveError < StandardError + end + class Middleware def initialize(app) @app = app @@ -317,9 +320,9 @@ def build_directives(context, nonce, nonce_directives) @directives.map do |directive, sources| if sources.is_a?(Array) if nonce && nonce_directive?(directive, nonce_directives) - "#{directive} #{build_directive(sources, context).join(' ')} 'nonce-#{nonce}'" + "#{directive} #{build_directive(directive, sources, context).join(' ')} 'nonce-#{nonce}'" else - "#{directive} #{build_directive(sources, context).join(' ')}" + "#{directive} #{build_directive(directive, sources, context).join(' ')}" end elsif sources directive @@ -329,8 +332,22 @@ def build_directives(context, nonce, nonce_directives) end end - def build_directive(sources, context) - sources.map { |source| resolve_source(source, context) } + def validate(directive, sources) + sources.flatten.each do |source| + if source.include?(";") || source != source.gsub(/[[:space:]]/, "") + raise InvalidDirectiveError, <<~MSG.squish + Invalid Content Security Policy #{directive}: "#{source}". + Directive values must not contain whitespace or semicolons. + Please use multiple arguments or other directive methods instead. + MSG + end + end + end + + def build_directive(directive, sources, context) + resolved_sources = sources.map { |source| resolve_source(source, context) } + + validate(directive, resolved_sources) end def resolve_source(source, context)
actionpack/test/dispatch/content_security_policy_test.rb+27 −0 modified@@ -23,6 +23,33 @@ def test_dup assert_equal copied.build, @policy.build end + def test_whitespace_validation + @policy.base_uri "https://some.url https://other.url" + + error = assert_raises(ActionDispatch::ContentSecurityPolicy::InvalidDirectiveError) do + @policy.build + end + assert_equal(<<~MSG.squish, error.message) + Invalid Content Security Policy base-uri: "https://some.url https://other.url". + Directive values must not contain whitespace or semicolons. + Please use multiple arguments or other directive methods instead. + MSG + end + + + def test_semicolon_validation + @policy.base_uri "https://some.url; script-src https://other.url" + + error = assert_raises(ActionDispatch::ContentSecurityPolicy::InvalidDirectiveError) do + @policy.build + end + assert_equal(<<~MSG.squish, error.message) + Invalid Content Security Policy base-uri: "https://some.url; script-src https://other.url". + Directive values must not contain whitespace or semicolons. + Please use multiple arguments or other directive methods instead. + MSG + end + def test_mappings @policy.script_src :data assert_equal "script-src data:", @policy.build
cb16a3bb515bAdd CSP directive validation
3 files changed · +55 −4
actionpack/CHANGELOG.md+7 −0 modified@@ -1,3 +1,10 @@ +* Add validation to content security policies to disallow spaces and semicolons. + Developers should use multiple arguments, and different directive methods instead. + + [CVE-2024-54133] + + *Gannon McGibbon* + ## Rails 7.0.8.6 (October 23, 2024) ## * No changes.
actionpack/lib/action_dispatch/http/content_security_policy.rb+21 −4 modified@@ -22,6 +22,9 @@ module ActionDispatch # :nodoc: # policy.report_uri "/csp-violation-report-endpoint" # end class ContentSecurityPolicy + class InvalidDirectiveError < StandardError + end + class Middleware CONTENT_TYPE = "Content-Type" POLICY = "Content-Security-Policy" @@ -316,9 +319,9 @@ def build_directives(context, nonce, nonce_directives) @directives.map do |directive, sources| if sources.is_a?(Array) if nonce && nonce_directive?(directive, nonce_directives) - "#{directive} #{build_directive(sources, context).join(' ')} 'nonce-#{nonce}'" + "#{directive} #{build_directive(directive, sources, context).join(' ')} 'nonce-#{nonce}'" else - "#{directive} #{build_directive(sources, context).join(' ')}" + "#{directive} #{build_directive(directive, sources, context).join(' ')}" end elsif sources directive @@ -328,8 +331,22 @@ def build_directives(context, nonce, nonce_directives) end end - def build_directive(sources, context) - sources.map { |source| resolve_source(source, context) } + def validate(directive, sources) + sources.flatten.each do |source| + if source.include?(";") || source != source.gsub(/[[:space:]]/, "") + raise InvalidDirectiveError, <<~MSG.squish + Invalid Content Security Policy #{directive}: "#{source}". + Directive values must not contain whitespace or semicolons. + Please use multiple arguments or other directive methods instead. + MSG + end + end + end + + def build_directive(directive, sources, context) + resolved_sources = sources.map { |source| resolve_source(source, context) } + + validate(directive, resolved_sources) end def resolve_source(source, context)
actionpack/test/dispatch/content_security_policy_test.rb+27 −0 modified@@ -23,6 +23,33 @@ def test_dup assert_equal copied.build, @policy.build end + def test_whitespace_validation + @policy.base_uri "https://some.url https://other.url" + + error = assert_raises(ActionDispatch::ContentSecurityPolicy::InvalidDirectiveError) do + @policy.build + end + assert_equal(<<~MSG.squish, error.message) + Invalid Content Security Policy base-uri: "https://some.url https://other.url". + Directive values must not contain whitespace or semicolons. + Please use multiple arguments or other directive methods instead. + MSG + end + + + def test_semicolon_validation + @policy.base_uri "https://some.url; script-src https://other.url" + + error = assert_raises(ActionDispatch::ContentSecurityPolicy::InvalidDirectiveError) do + @policy.build + end + assert_equal(<<~MSG.squish, error.message) + Invalid Content Security Policy base-uri: "https://some.url; script-src https://other.url". + Directive values must not contain whitespace or semicolons. + Please use multiple arguments or other directive methods instead. + MSG + end + def test_mappings @policy.script_src :data assert_equal "script-src data:", @policy.build
2e3f41e4538bAdd CSP directive validation
3 files changed · +56 −4
actionpack/CHANGELOG.md+8 −0 modified@@ -1,3 +1,11 @@ +* Add validation to content security policies to disallow spaces and semicolons. + Developers should use multiple arguments, and different directive methods instead. + + [CVE-2024-54133] + + *Gannon McGibbon* + + ## Rails 8.0.0 (November 07, 2024) ## * No changes.
actionpack/lib/action_dispatch/http/content_security_policy.rb+21 −4 modified@@ -26,6 +26,9 @@ module ActionDispatch # :nodoc: # policy.report_uri "/csp-violation-report-endpoint" # end class ContentSecurityPolicy + class InvalidDirectiveError < StandardError + end + class Middleware def initialize(app) @app = app @@ -320,9 +323,9 @@ def build_directives(context, nonce, nonce_directives) @directives.map do |directive, sources| if sources.is_a?(Array) if nonce && nonce_directive?(directive, nonce_directives) - "#{directive} #{build_directive(sources, context).join(' ')} 'nonce-#{nonce}'" + "#{directive} #{build_directive(directive, sources, context).join(' ')} 'nonce-#{nonce}'" else - "#{directive} #{build_directive(sources, context).join(' ')}" + "#{directive} #{build_directive(directive, sources, context).join(' ')}" end elsif sources directive @@ -332,8 +335,22 @@ def build_directives(context, nonce, nonce_directives) end end - def build_directive(sources, context) - sources.map { |source| resolve_source(source, context) } + def validate(directive, sources) + sources.flatten.each do |source| + if source.include?(";") || source != source.gsub(/[[:space:]]/, "") + raise InvalidDirectiveError, <<~MSG.squish + Invalid Content Security Policy #{directive}: "#{source}". + Directive values must not contain whitespace or semicolons. + Please use multiple arguments or other directive methods instead. + MSG + end + end + end + + def build_directive(directive, sources, context) + resolved_sources = sources.map { |source| resolve_source(source, context) } + + validate(directive, resolved_sources) end def resolve_source(source, context)
actionpack/test/dispatch/content_security_policy_test.rb+27 −0 modified@@ -23,6 +23,33 @@ def test_dup assert_equal copied.build, @policy.build end + def test_whitespace_validation + @policy.base_uri "https://some.url https://other.url" + + error = assert_raises(ActionDispatch::ContentSecurityPolicy::InvalidDirectiveError) do + @policy.build + end + assert_equal(<<~MSG.squish, error.message) + Invalid Content Security Policy base-uri: "https://some.url https://other.url". + Directive values must not contain whitespace or semicolons. + Please use multiple arguments or other directive methods instead. + MSG + end + + + def test_semicolon_validation + @policy.base_uri "https://some.url; script-src https://other.url" + + error = assert_raises(ActionDispatch::ContentSecurityPolicy::InvalidDirectiveError) do + @policy.build + end + assert_equal(<<~MSG.squish, error.message) + Invalid Content Security Policy base-uri: "https://some.url; script-src https://other.url". + Directive values must not contain whitespace or semicolons. + Please use multiple arguments or other directive methods instead. + MSG + end + def test_mappings @policy.script_src :data assert_equal "script-src data:", @policy.build
3da2479cfe1eAdd CSP directive validation
3 files changed · +56 −4
actionpack/CHANGELOG.md+8 −0 modified@@ -1,3 +1,11 @@ +* Add validation to content security policies to disallow spaces and semicolons. + Developers should use multiple arguments, and different directive methods instead. + + [CVE-2024-54133] + + *Gannon McGibbon* + + ## Rails 7.2.2 (October 30, 2024) ## * Fix non-GET requests not updating cookies in `ActionController::TestCase`.
actionpack/lib/action_dispatch/http/content_security_policy.rb+21 −4 modified@@ -26,6 +26,9 @@ module ActionDispatch # :nodoc: # policy.report_uri "/csp-violation-report-endpoint" # end class ContentSecurityPolicy + class InvalidDirectiveError < StandardError + end + class Middleware def initialize(app) @app = app @@ -319,9 +322,9 @@ def build_directives(context, nonce, nonce_directives) @directives.map do |directive, sources| if sources.is_a?(Array) if nonce && nonce_directive?(directive, nonce_directives) - "#{directive} #{build_directive(sources, context).join(' ')} 'nonce-#{nonce}'" + "#{directive} #{build_directive(directive, sources, context).join(' ')} 'nonce-#{nonce}'" else - "#{directive} #{build_directive(sources, context).join(' ')}" + "#{directive} #{build_directive(directive, sources, context).join(' ')}" end elsif sources directive @@ -331,8 +334,22 @@ def build_directives(context, nonce, nonce_directives) end end - def build_directive(sources, context) - sources.map { |source| resolve_source(source, context) } + def validate(directive, sources) + sources.flatten.each do |source| + if source.include?(";") || source != source.gsub(/[[:space:]]/, "") + raise InvalidDirectiveError, <<~MSG.squish + Invalid Content Security Policy #{directive}: "#{source}". + Directive values must not contain whitespace or semicolons. + Please use multiple arguments or other directive methods instead. + MSG + end + end + end + + def build_directive(directive, sources, context) + resolved_sources = sources.map { |source| resolve_source(source, context) } + + validate(directive, resolved_sources) end def resolve_source(source, context)
actionpack/test/dispatch/content_security_policy_test.rb+27 −0 modified@@ -23,6 +23,33 @@ def test_dup assert_equal copied.build, @policy.build end + def test_whitespace_validation + @policy.base_uri "https://some.url https://other.url" + + error = assert_raises(ActionDispatch::ContentSecurityPolicy::InvalidDirectiveError) do + @policy.build + end + assert_equal(<<~MSG.squish, error.message) + Invalid Content Security Policy base-uri: "https://some.url https://other.url". + Directive values must not contain whitespace or semicolons. + Please use multiple arguments or other directive methods instead. + MSG + end + + + def test_semicolon_validation + @policy.base_uri "https://some.url; script-src https://other.url" + + error = assert_raises(ActionDispatch::ContentSecurityPolicy::InvalidDirectiveError) do + @policy.build + end + assert_equal(<<~MSG.squish, error.message) + Invalid Content Security Policy base-uri: "https://some.url; script-src https://other.url". + Directive values must not contain whitespace or semicolons. + Please use multiple arguments or other directive methods instead. + MSG + end + def test_mappings @policy.script_src :data assert_equal "script-src data:", @policy.build
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- github.com/advisories/GHSA-vfm5-rmrh-j26vghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-54133ghsaADVISORY
- github.com/rails/rails/commit/2e3f41e4538b9ca1044357f6644f037bbb7c6c49nvdWEB
- github.com/rails/rails/commit/3da2479cfe1e00177114b17e496213c40d286b3anvdWEB
- github.com/rails/rails/commit/5558e72f22fc69c1c407b31ac5fb3b4ce087b542nvdWEB
- github.com/rails/rails/commit/cb16a3bb515b5d769f73926d9757270ace691f1dnvdWEB
- github.com/rails/rails/security/advisories/GHSA-vfm5-rmrh-j26vnvdWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/actionpack/CVE-2024-54133.ymlghsaWEB
- security.netapp.com/advisory/ntap-20250306-0010ghsaWEB
- security.netapp.com/advisory/ntap-20250306-0010/nvd
News mentions
0No linked articles in our index yet.