VYPR
Medium severity4.0NVD Advisory· Published Jan 9, 2025· Updated Apr 15, 2026

CVE-2023-28362

CVE-2023-28362

Description

The redirect_to method in Rails allows provided values to contain characters which are not legal in an HTTP header value. This results in the potential for downstream services which enforce RFC compliance on HTTP response headers to remove the assigned Location header.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
actionpackRubyGems
< 6.1.7.46.1.7.4
actionpackRubyGems
>= 7.0.0, < 7.0.5.17.0.5.1

Patches

3
69e37c84e3f7

Added check for illegal HTTP header value in redirect_to

https://github.com/rails/railsZack DeveauMay 12, 2023via ghsa
2 files changed · +36 1
  • actionpack/lib/action_controller/metal/redirecting.rb+18 1 modified
    @@ -9,6 +9,8 @@ module Redirecting
     
         class UnsafeRedirectError < StandardError; end
     
    +    ILLEGAL_HEADER_VALUE_REGEX = /[\x00-\x08\x0A-\x1F]/.freeze
    +
         included do
           mattr_accessor :raise_on_open_redirects, default: false
         end
    @@ -86,7 +88,11 @@ def redirect_to(options = {}, response_options = {})
           allow_other_host = response_options.delete(:allow_other_host) { _allow_other_host }
     
           self.status        = _extract_redirect_to_status(options, response_options)
    -      self.location      = _enforce_open_redirect_protection(_compute_redirect_to_location(request, options), allow_other_host: allow_other_host)
    +
    +      redirect_to_location = _compute_redirect_to_location(request, options)
    +      _ensure_url_is_http_header_safe(redirect_to_location)
    +
    +      self.location      = _enforce_open_redirect_protection(redirect_to_location, allow_other_host: allow_other_host)
           self.response_body = ""
         end
     
    @@ -204,5 +210,16 @@ def _url_host_allowed?(url)
           rescue ArgumentError, URI::Error
             false
           end
    +
    +      def _ensure_url_is_http_header_safe(url)
    +        # Attempt to comply with the set of valid token characters
    +        # defined for an HTTP header value in
    +        # https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6
    +        if url.match(ILLEGAL_HEADER_VALUE_REGEX)
    +          msg = "The redirect URL #{url} contains one or more illegal HTTP header field character. " \
    +            "Set of legal characters defined in https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6"
    +          raise UnsafeRedirectError, msg
    +        end
    +      end
       end
     end
    
  • actionpack/test/controller/redirect_test.rb+18 0 modified
    @@ -104,6 +104,10 @@ def unsafe_redirect_protocol_relative_triple_slash
         redirect_to "///www.rubyonrails.org/"
       end
     
    +  def unsafe_redirect_with_illegal_http_header_value_character
    +    redirect_to "javascript:alert(document.domain)\b", allow_other_host: true
    +  end
    +
       def only_path_redirect
         redirect_to action: "other_host", only_path: true
       end
    @@ -556,6 +560,20 @@ def test_unsafe_redirect_with_protocol_relative_triple_slash_url
         end
       end
     
    +  def test_unsafe_redirect_with_illegal_http_header_value_character
    +    with_raise_on_open_redirects do
    +      error = assert_raise(ActionController::Redirecting::UnsafeRedirectError) do
    +        get :unsafe_redirect_with_illegal_http_header_value_character
    +      end
    +
    +      msg = "The redirect URL javascript:alert(document.domain)\b contains one or more illegal HTTP header field character. " \
    +        "Set of legal characters defined in https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6"
    +
    +      assert_equal msg, error.message
    +    end
    +  end
    +
    +
       def test_only_path_redirect
         with_raise_on_open_redirects do
           get :only_path_redirect
    
1c3f93d1e90a

Added check for illegal HTTP header value in redirect_to

https://github.com/rails/railsZack DeveauMay 12, 2023via ghsa
2 files changed · +37 1
  • actionpack/lib/action_controller/metal/redirecting.rb+20 1 modified
    @@ -7,6 +7,10 @@ module Redirecting
         include AbstractController::Logger
         include ActionController::UrlFor
     
    +    ILLEGAL_HEADER_VALUE_REGEX = /[\x00-\x08\x0A-\x1F]/.freeze
    +
    +    class UnsafeRedirectError < StandardError; end
    +
         # Redirects the browser to the target specified in +options+. This parameter can be any one of:
         #
         # * <tt>Hash</tt> - The URL will be generated by calling url_for with the +options+.
    @@ -60,7 +64,11 @@ def redirect_to(options = {}, response_options = {})
           raise AbstractController::DoubleRenderError if response_body
     
           self.status        = _extract_redirect_to_status(options, response_options)
    -      self.location      = _compute_redirect_to_location(request, options)
    +
    +      redirect_to_location = _compute_redirect_to_location(request, options)
    +      _ensure_url_is_http_header_safe(redirect_to_location)
    +
    +      self.location      = redirect_to_location
           self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.unwrapped_html_escape(response.location)}\">redirected</a>.</body></html>"
         end
     
    @@ -129,5 +137,16 @@ def _url_host_allowed?(url)
           rescue ArgumentError, URI::Error
             false
           end
    +
    +      def _ensure_url_is_http_header_safe(url)
    +        # Attempt to comply with the set of valid token characters
    +        # defined for an HTTP header value in
    +        # https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6
    +        if url.match(ILLEGAL_HEADER_VALUE_REGEX)
    +          msg = "The redirect URL #{url} contains one or more illegal HTTP header field character. " \
    +            "Set of legal characters defined in https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6"
    +          raise UnsafeRedirectError, msg
    +        end
    +      end
       end
     end
    
  • actionpack/test/controller/redirect_test.rb+17 0 modified
    @@ -153,6 +153,11 @@ def redirect_with_null_bytes
         redirect_to "\000/lol\r\nwat"
       end
     
    +  def unsafe_redirect_with_illegal_http_header_value_character
    +    redirect_to "javascript:alert(document.domain)\b"
    +  end
    +
    +
       def rescue_errors(e) raise e end
     
       private
    @@ -437,6 +442,18 @@ def test_redirect_to_with_block_and_accepted_options
           assert_redirected_to "http://test.host/redirect/hello_world"
         end
       end
    +
    +  def test_unsafe_redirect_with_illegal_http_header_value_character
    +    error = assert_raise(ActionController::Redirecting::UnsafeRedirectError) do
    +      get :unsafe_redirect_with_illegal_http_header_value_character
    +    end
    +
    +    msg = "The redirect URL javascript:alert(document.domain)\b contains one or more illegal HTTP header field character. " \
    +      "Set of legal characters defined in https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6"
    +
    +    assert_equal msg, error.message
    +  end
    +
     end
     
     module ModuleTest
    
c9ab9b32bcdc

Added check for illegal HTTP header value in redirect_to

https://github.com/rails/railsZack DeveauMay 11, 2023via ghsa
2 files changed · +35 1
  • actionpack/lib/action_controller/metal/redirecting.rb+18 1 modified
    @@ -4,6 +4,8 @@ module ActionController
       module Redirecting
         extend ActiveSupport::Concern
     
    +    ILLEGAL_HEADER_VALUE_REGEX = /[\x00-\x08\x0A-\x1F]/.freeze
    +
         include AbstractController::Logger
         include ActionController::UrlFor
     
    @@ -86,7 +88,11 @@ def redirect_to(options = {}, response_options = {})
           allow_other_host = response_options.delete(:allow_other_host) { _allow_other_host }
     
           self.status        = _extract_redirect_to_status(options, response_options)
    -      self.location      = _enforce_open_redirect_protection(_compute_redirect_to_location(request, options), allow_other_host: allow_other_host)
    +
    +      redirect_to_location = _compute_redirect_to_location(request, options)
    +      _ensure_url_is_http_header_safe(redirect_to_location)
    +
    +      self.location      = _enforce_open_redirect_protection(redirect_to_location, allow_other_host: allow_other_host)
           self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.unwrapped_html_escape(response.location)}\">redirected</a>.</body></html>"
         end
     
    @@ -204,5 +210,16 @@ def _url_host_allowed?(url)
           rescue ArgumentError, URI::Error
             false
           end
    +
    +      def _ensure_url_is_http_header_safe(url)
    +        # Attempt to comply with the set of valid token characters
    +        # defined for an HTTP header value in
    +        # https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6
    +        if url.match(ILLEGAL_HEADER_VALUE_REGEX)
    +          msg = "The redirect URL #{url} contains one or more illegal HTTP header field character. " \
    +            "Set of legal characters defined in https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6"
    +          raise UnsafeRedirectError, msg
    +        end
    +      end
       end
     end
    
  • actionpack/test/controller/redirect_test.rb+17 0 modified
    @@ -104,6 +104,10 @@ def unsafe_redirect_protocol_relative_triple_slash
         redirect_to "///www.rubyonrails.org/"
       end
     
    +  def unsafe_redirect_with_illegal_http_header_value_character
    +    redirect_to "javascript:alert(document.domain)\b", allow_other_host: true
    +  end
    +
       def only_path_redirect
         redirect_to action: "other_host", only_path: true
       end
    @@ -556,6 +560,19 @@ def test_unsafe_redirect_with_protocol_relative_triple_slash_url
         end
       end
     
    +  def test_unsafe_redirect_with_illegal_http_header_value_character
    +    with_raise_on_open_redirects do
    +      error = assert_raise(ActionController::Redirecting::UnsafeRedirectError) do
    +        get :unsafe_redirect_with_illegal_http_header_value_character
    +      end
    +
    +      msg = "The redirect URL javascript:alert(document.domain)\b contains one or more illegal HTTP header field character. " \
    +        "Set of legal characters defined in https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6"
    +
    +      assert_equal msg, error.message
    +    end
    +  end
    +
       def test_only_path_redirect
         with_raise_on_open_redirects do
           get :only_path_redirect
    

Vulnerability mechanics

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

References

9

News mentions

0

No linked articles in our index yet.