VYPR
Moderate severityNVD Advisory· Published Mar 19, 2020· Updated Aug 4, 2024

Possible XSS vulnerability in ActionView

CVE-2020-5267

Description

In ActionView before versions 6.0.2.2 and 5.2.4.2, there is a possible XSS vulnerability in ActionView's JavaScript literal escape helpers. Views that use the j or escape_javascript methods may be susceptible to XSS attacks. The issue is fixed in versions 6.0.2.2 and 5.2.4.2.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

ActionView's JavaScript literal escape helpers (`j`, `escape_javascript`) are vulnerable to XSS when used inside template literals (`${...}` or backticks).

Vulnerability

CVE-2020-5267 is an XSS vulnerability in Ruby on Rails' ActionView, affecting the j and escape_javascript helper methods. These methods are designed to escape input for JavaScript string literals, but they did not escape the backtick (` `) character or the dollar sign ($`) in the context of ES6 template literals [2][4]. An attacker can break out of the intended string literal and inject arbitrary JavaScript code.

Exploitation

The attack surface is any view that passes user-controlled input through j or escape_javascript inside a template literal (backtick-quoted string) in a ` An attacker supplying a payload containing ` and ${...} sequences can craft a malicious string that closes the template literal and executes attacker-controlled code. No authentication is required if the input originates from an untrusted source (e.g., request parameters, user-generated content) [1][2]. ## Impact Successful exploitation allows an attacker to perform cross-site scripting (XSS) attacks. The attacker can execute arbitrary JavaScript in the victim's browser context, potentially leading to session theft, credential harvesting, or unauthorized actions. The CVSS metrics (not fully assessed by NVD as of the reference) indicate a high severity due to the lack of proper input sanitization [1]. ## Mitigation The vulnerability is patched in Rails versions 5.2.4.2 and 6.0.2.2. Users on unsupported versions should upgrade immediately. For those unable to upgrade immediately, a monkey patch is provided that explicitly escapes backtick and dollar sign characters in the JS_ESCAPE_MAP` and updates the escaping regex [2][4]. No workarounds are available for versions earlier than 5.2.

AI Insight generated on May 21, 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
actionviewRubyGems
< 5.2.4.25.2.4.2
actionviewRubyGems
>= 6.0.0, < 6.0.2.26.0.2.2

Affected products

19

Patches

3
157920aead96

Preparing for 6.0.2.2 release

https://github.com/rails/railsAaron PattersonMar 19, 2020via osv
17 files changed · +17 17
  • actioncable/lib/action_cable/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 6
         MINOR = 0
         TINY  = 2
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • actioncable/package.json+1 1 modified
    @@ -1,6 +1,6 @@
     {
       "name": "@rails/actioncable",
    -  "version": "6.0.2-1",
    +  "version": "6.0.2-2",
       "description": "WebSocket framework for Ruby on Rails.",
       "main": "app/assets/javascripts/action_cable.js",
       "files": [
    
  • actionmailbox/lib/action_mailbox/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 6
         MINOR = 0
         TINY  = 2
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • actionmailer/lib/action_mailer/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 6
         MINOR = 0
         TINY  = 2
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • actionpack/lib/action_pack/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 6
         MINOR = 0
         TINY  = 2
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • actiontext/lib/action_text/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 6
         MINOR = 0
         TINY  = 2
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • actiontext/package.json+1 1 modified
    @@ -1,6 +1,6 @@
     {
       "name": "@rails/actiontext",
    -  "version": "6.0.2-1",
    +  "version": "6.0.2-2",
       "description": "Edit and display rich text in Rails applications",
       "main": "app/javascript/actiontext/index.js",
       "files": [
    
  • actionview/lib/action_view/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 6
         MINOR = 0
         TINY  = 2
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • actionview/package.json+1 1 modified
    @@ -1,6 +1,6 @@
     {
       "name": "@rails/ujs",
    -  "version": "6.0.2-1",
    +  "version": "6.0.2-2",
       "description": "Ruby on Rails unobtrusive scripting adapter",
       "main": "lib/assets/compiled/rails-ujs.js",
       "files": [
    
  • activejob/lib/active_job/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 6
         MINOR = 0
         TINY  = 2
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • activemodel/lib/active_model/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 6
         MINOR = 0
         TINY  = 2
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • activerecord/lib/active_record/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 6
         MINOR = 0
         TINY  = 2
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • activestorage/lib/active_storage/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 6
         MINOR = 0
         TINY  = 2
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • activestorage/package.json+1 1 modified
    @@ -1,6 +1,6 @@
     {
       "name": "@rails/activestorage",
    -  "version": "6.0.2-1",
    +  "version": "6.0.2-2",
       "description": "Attach cloud and local files in Rails applications",
       "main": "app/assets/javascripts/activestorage.js",
       "files": [
    
  • activesupport/lib/active_support/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 6
         MINOR = 0
         TINY  = 2
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • railties/lib/rails/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 6
         MINOR = 0
         TINY  = 2
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 6
         MINOR = 0
         TINY  = 2
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
4dcc5435e956

update version

https://github.com/rails/railsAaron PattersonMar 19, 2020via osv
16 files changed · +51 51
  • actioncable/lib/action_cable/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 5
         MINOR = 2
         TINY  = 4
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • actioncable/package.json+1 1 modified
    @@ -1,6 +1,6 @@
     {
       "name": "actioncable",
    -  "version": "5.2.4-1",
    +  "version": "5.2.4-2",
       "description": "WebSocket framework for Ruby on Rails.",
       "main": "lib/assets/compiled/action_cable.js",
       "files": [
    
  • actionmailer/lib/action_mailer/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 5
         MINOR = 2
         TINY  = 4
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • actionpack/lib/action_pack/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 5
         MINOR = 2
         TINY  = 4
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • actionview/lib/action_view/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 5
         MINOR = 2
         TINY  = 4
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • actionview/package.json+1 1 modified
    @@ -1,6 +1,6 @@
     {
       "name": "rails-ujs",
    -  "version": "5.2.4-1",
    +  "version": "5.2.4-2",
       "description": "Ruby on Rails unobtrusive scripting adapter",
       "main": "lib/assets/compiled/rails-ujs.js",
       "files": [
    
  • activejob/lib/active_job/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 5
         MINOR = 2
         TINY  = 4
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • activemodel/lib/active_model/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 5
         MINOR = 2
         TINY  = 4
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • activerecord/lib/active_record/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 5
         MINOR = 2
         TINY  = 4
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • activestorage/lib/active_storage/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 5
         MINOR = 2
         TINY  = 4
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • activestorage/package.json+1 1 modified
    @@ -1,6 +1,6 @@
     {
       "name": "activestorage",
    -  "version": "5.2.4-1",
    +  "version": "5.2.4-2",
       "description": "Attach cloud and local files in Rails applications",
       "main": "app/assets/javascripts/activestorage.js",
       "files": [
    
  • activesupport/lib/active_support/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 5
         MINOR = 2
         TINY  = 4
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • Gemfile.lock+36 36 modified
    @@ -26,63 +26,63 @@ GIT
     PATH
       remote: .
       specs:
    -    actioncable (5.2.4.1)
    -      actionpack (= 5.2.4.1)
    +    actioncable (5.2.4.2)
    +      actionpack (= 5.2.4.2)
           nio4r (~> 2.0)
           websocket-driver (>= 0.6.1)
    -    actionmailer (5.2.4.1)
    -      actionpack (= 5.2.4.1)
    -      actionview (= 5.2.4.1)
    -      activejob (= 5.2.4.1)
    +    actionmailer (5.2.4.2)
    +      actionpack (= 5.2.4.2)
    +      actionview (= 5.2.4.2)
    +      activejob (= 5.2.4.2)
           mail (~> 2.5, >= 2.5.4)
           rails-dom-testing (~> 2.0)
    -    actionpack (5.2.4.1)
    -      actionview (= 5.2.4.1)
    -      activesupport (= 5.2.4.1)
    +    actionpack (5.2.4.2)
    +      actionview (= 5.2.4.2)
    +      activesupport (= 5.2.4.2)
           rack (~> 2.0, >= 2.0.8)
           rack-test (>= 0.6.3)
           rails-dom-testing (~> 2.0)
           rails-html-sanitizer (~> 1.0, >= 1.0.2)
    -    actionview (5.2.4.1)
    -      activesupport (= 5.2.4.1)
    +    actionview (5.2.4.2)
    +      activesupport (= 5.2.4.2)
           builder (~> 3.1)
           erubi (~> 1.4)
           rails-dom-testing (~> 2.0)
           rails-html-sanitizer (~> 1.0, >= 1.0.3)
    -    activejob (5.2.4.1)
    -      activesupport (= 5.2.4.1)
    +    activejob (5.2.4.2)
    +      activesupport (= 5.2.4.2)
           globalid (>= 0.3.6)
    -    activemodel (5.2.4.1)
    -      activesupport (= 5.2.4.1)
    -    activerecord (5.2.4.1)
    -      activemodel (= 5.2.4.1)
    -      activesupport (= 5.2.4.1)
    +    activemodel (5.2.4.2)
    +      activesupport (= 5.2.4.2)
    +    activerecord (5.2.4.2)
    +      activemodel (= 5.2.4.2)
    +      activesupport (= 5.2.4.2)
           arel (>= 9.0)
    -    activestorage (5.2.4.1)
    -      actionpack (= 5.2.4.1)
    -      activerecord (= 5.2.4.1)
    +    activestorage (5.2.4.2)
    +      actionpack (= 5.2.4.2)
    +      activerecord (= 5.2.4.2)
           marcel (~> 0.3.1)
    -    activesupport (5.2.4.1)
    +    activesupport (5.2.4.2)
           concurrent-ruby (~> 1.0, >= 1.0.2)
           i18n (>= 0.7, < 2)
           minitest (~> 5.1)
           tzinfo (~> 1.1)
    -    rails (5.2.4.1)
    -      actioncable (= 5.2.4.1)
    -      actionmailer (= 5.2.4.1)
    -      actionpack (= 5.2.4.1)
    -      actionview (= 5.2.4.1)
    -      activejob (= 5.2.4.1)
    -      activemodel (= 5.2.4.1)
    -      activerecord (= 5.2.4.1)
    -      activestorage (= 5.2.4.1)
    -      activesupport (= 5.2.4.1)
    +    rails (5.2.4.2)
    +      actioncable (= 5.2.4.2)
    +      actionmailer (= 5.2.4.2)
    +      actionpack (= 5.2.4.2)
    +      actionview (= 5.2.4.2)
    +      activejob (= 5.2.4.2)
    +      activemodel (= 5.2.4.2)
    +      activerecord (= 5.2.4.2)
    +      activestorage (= 5.2.4.2)
    +      activesupport (= 5.2.4.2)
           bundler (>= 1.3.0)
    -      railties (= 5.2.4.1)
    +      railties (= 5.2.4.2)
           sprockets-rails (>= 2.0.0)
    -    railties (5.2.4.1)
    -      actionpack (= 5.2.4.1)
    -      activesupport (= 5.2.4.1)
    +    railties (5.2.4.2)
    +      actionpack (= 5.2.4.2)
    +      activesupport (= 5.2.4.2)
           method_source
           rake (>= 0.8.7)
           thor (>= 0.19.0, < 2.0)
    
  • RAILS_VERSION+1 1 modified
    @@ -1 +1 @@
    -5.2.4.1
    +5.2.4.2
    
  • railties/lib/rails/gem_version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 5
         MINOR = 2
         TINY  = 4
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
  • version.rb+1 1 modified
    @@ -10,7 +10,7 @@ module VERSION
         MAJOR = 5
         MINOR = 2
         TINY  = 4
    -    PRE   = "1"
    +    PRE   = "2"
     
         STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
       end
    
033a738817ab

Fix possible XSS vector in JS escape helper

https://github.com/rails/railsAaron PattersonMar 12, 2020via ghsa
2 files changed · +12 2
  • actionview/lib/action_view/helpers/javascript_helper.rb+4 2 modified
    @@ -12,7 +12,9 @@ module JavaScriptHelper
             "\n"    => '\n',
             "\r"    => '\n',
             '"'     => '\\"',
    -        "'"     => "\\'"
    +        "'"     => "\\'",
    +        "`"     => "\\`",
    +        "$"     => "\\$"
           }
     
           JS_ESCAPE_MAP[(+"\342\200\250").force_encoding(Encoding::UTF_8).encode!] = "&#x2028;"
    @@ -29,7 +31,7 @@ def escape_javascript(javascript)
             if javascript.empty?
               result = ""
             else
    -          result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u, JS_ESCAPE_MAP)
    +          result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"']|[`]|[$])/u, JS_ESCAPE_MAP)
             end
             javascript.html_safe? ? result.html_safe : result
           end
    
  • actionview/test/template/javascript_helper_test.rb+8 0 modified
    @@ -36,6 +36,14 @@ def test_escape_javascript
         assert_equal %(dont <\\/close> tags), j(%(dont </close> tags))
       end
     
    +  def test_escape_backtick
    +    assert_equal "\\`", escape_javascript("`")
    +  end
    +
    +  def test_escape_dollar_sign
    +    assert_equal "\\$", escape_javascript("$")
    +  end
    +
       def test_escape_javascript_with_safebuffer
         given = %('quoted' "double-quoted" new-line:\n </closed>)
         expect = %(\\'quoted\\' \\"double-quoted\\" new-line:\\n <\\/closed>)
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

11

News mentions

0

No linked articles in our index yet.