VYPR
Low severityOSV Advisory· Published Dec 10, 2024· Updated Apr 15, 2026

CVE-2024-54133

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.

PackageAffected versionsPatched versions
actionpackRubyGems
>= 5.2.0, < 7.0.8.77.0.8.7
actionpackRubyGems
>= 7.1.0, < 7.1.5.17.1.5.1
actionpackRubyGems
>= 7.2.0, < 7.2.2.17.2.2.1
actionpackRubyGems
>= 8.0.0, < 8.0.0.18.0.0.1

Affected products

17

Patches

8
5558e72f22fc

Add CSP directive validation

https://github.com/rails/railsGannon McGibbonOct 16, 2024via ghsa
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
    
cb16a3bb515b

Add CSP directive validation

https://github.com/rails/railsGannon McGibbonOct 16, 2024via ghsa
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
    
2e3f41e4538b

Add CSP directive validation

https://github.com/rails/railsGannon McGibbonOct 16, 2024via ghsa
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
    
3da2479cfe1e

Add CSP directive validation

https://github.com/rails/railsGannon McGibbonOct 16, 2024via ghsa
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

News mentions

0

No linked articles in our index yet.