VYPR
Medium severity4.2NVD Advisory· Published Aug 29, 2025· Updated Apr 15, 2026

CVE-2025-58067

CVE-2025-58067

Description

Basecamp's Google Sign-In adds Google sign-in to Rails applications. Prior to version 1.3.1, it is possible to redirect a user to another origin if the "proceed_to" value in the session store is set to a protocol-relative URL. Normally the value of this URL is only written and read by the library or the calling application. However, it may be possible to set this session value from a malicious site with a form submission. Any Rails applications using the google_sign_in gem may be vulnerable, if this vector can be chained with another attack that is able to modify the OAuth2 request parameters. This issue has been patched in version 1.3.1. There are no workarounds.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
google_sign_inRubyGems
< 1.3.11.3.1

Affected products

1

Patches

2
e7f2a9ab59fe

version bump to v1.3.1

https://github.com/basecamp/google_sign_inMike DalessioAug 29, 2025via osv
8 files changed · +8 16
  • Gemfile.lock+1 1 modified
    @@ -1,7 +1,7 @@
     PATH
       remote: .
       specs:
    -    google_sign_in (1.3.0)
    +    google_sign_in (1.3.1)
           google-id-token (>= 1.4.0)
           oauth2 (>= 1.4.0)
           rails (>= 6.1.0)
    
  • gemfiles/rails_6.1.gemfile.lock+1 1 modified
    @@ -1,7 +1,7 @@
     PATH
       remote: ..
       specs:
    -    google_sign_in (1.3.0)
    +    google_sign_in (1.3.1)
           google-id-token (>= 1.4.0)
           oauth2 (>= 1.4.0)
           rails (>= 6.1.0)
    
  • gemfiles/rails_7.0.gemfile.lock+1 2 modified
    @@ -1,7 +1,7 @@
     PATH
       remote: ..
       specs:
    -    google_sign_in (1.3.0)
    +    google_sign_in (1.3.1)
           google-id-token (>= 1.4.0)
           oauth2 (>= 1.4.0)
           rails (>= 6.1.0)
    @@ -247,7 +247,6 @@ DEPENDENCIES
       byebug
       google_sign_in!
       jwt (>= 1.5.6)
    -  mutex_m
       rails (~> 7.0)
       rake
       webmock (>= 3.4.2)
    
  • gemfiles/rails_7.1.gemfile.lock+1 2 modified
    @@ -1,7 +1,7 @@
     PATH
       remote: ..
       specs:
    -    google_sign_in (1.3.0)
    +    google_sign_in (1.3.1)
           google-id-token (>= 1.4.0)
           oauth2 (>= 1.4.0)
           rails (>= 6.1.0)
    @@ -247,7 +247,6 @@ DEPENDENCIES
       byebug
       google_sign_in!
       jwt (>= 1.5.6)
    -  mutex_m
       rails (~> 7.1)
       rake
       webmock (>= 3.4.2)
    
  • gemfiles/rails_7.2.gemfile.lock+1 3 modified
    @@ -1,7 +1,7 @@
     PATH
       remote: ..
       specs:
    -    google_sign_in (1.3.0)
    +    google_sign_in (1.3.1)
           google-id-token (>= 1.4.0)
           oauth2 (>= 1.4.0)
           rails (>= 6.1.0)
    @@ -137,7 +137,6 @@ GEM
         minitest (5.25.5)
         multi_xml (0.7.2)
           bigdecimal (~> 3.1)
    -    mutex_m (0.3.0)
         net-http (0.6.0)
           uri
         net-imap (0.5.9)
    @@ -242,7 +241,6 @@ DEPENDENCIES
       byebug
       google_sign_in!
       jwt (>= 1.5.6)
    -  mutex_m
       rails (~> 7.2)
       rake
       webmock (>= 3.4.2)
    
  • gemfiles/rails_8.0.gemfile.lock+1 3 modified
    @@ -1,7 +1,7 @@
     PATH
       remote: ..
       specs:
    -    google_sign_in (1.3.0)
    +    google_sign_in (1.3.1)
           google-id-token (>= 1.4.0)
           oauth2 (>= 1.4.0)
           rails (>= 6.1.0)
    @@ -137,7 +137,6 @@ GEM
         minitest (5.25.5)
         multi_xml (0.7.2)
           bigdecimal (~> 3.1)
    -    mutex_m (0.3.0)
         net-http (0.6.0)
           uri
         net-imap (0.5.9)
    @@ -242,7 +241,6 @@ DEPENDENCIES
       byebug
       google_sign_in!
       jwt (>= 1.5.6)
    -  mutex_m
       rails (~> 8.0)
       rake
       webmock (>= 3.4.2)
    
  • gemfiles/rails_edge.gemfile.lock+1 3 modified
    @@ -102,7 +102,7 @@ GIT
     PATH
       remote: ..
       specs:
    -    google_sign_in (1.3.0)
    +    google_sign_in (1.3.1)
           google-id-token (>= 1.4.0)
           oauth2 (>= 1.4.0)
           rails (>= 6.1.0)
    @@ -169,7 +169,6 @@ GEM
         minitest (5.25.5)
         multi_xml (0.7.2)
           bigdecimal (~> 3.1)
    -    mutex_m (0.3.0)
         net-http (0.6.0)
           uri
         net-imap (0.5.9)
    @@ -253,7 +252,6 @@ DEPENDENCIES
       byebug
       google_sign_in!
       jwt (>= 1.5.6)
    -  mutex_m
       rails!
       rake
       webmock (>= 3.4.2)
    
  • google_sign_in.gemspec+1 1 modified
    @@ -1,6 +1,6 @@
     Gem::Specification.new do |s|
       s.name     = 'google_sign_in'
    -  s.version  = '1.3.0'
    +  s.version  = '1.3.1'
       s.authors  = ['David Heinemeier Hansson', 'George Claghorn']
       s.email    = ['david@basecamp.com', 'george@basecamp.com']
       s.summary  = 'Sign in (or up) with Google for Rails applications'
    
e97aef4626b1

Merge pull request #75 from basecamp/flavorjones/handle-invalid-paths

https://github.com/basecamp/google_sign_inMike DalessioAug 29, 2025via ghsa
3 files changed · +89 8
  • lib/google_sign_in/redirect_protector.rb+14 7 modified
    @@ -9,20 +9,27 @@ class Violation < StandardError; end
         QUALIFIED_URL_PATTERN = /\A#{URI::DEFAULT_PARSER.make_regexp}\z/
     
         def ensure_same_origin(target, source)
    -      if (target =~ QUALIFIED_URL_PATTERN && origin_of(target) == origin_of(source)) ||
    -         target =~ URI::DEFAULT_PARSER.regexp[:ABS_PATH]
    -        return
    +      unless uri_same_origin?(target, source) || absolute_path?(target)
    +        raise Violation, "Redirect target #{target.inspect} does not have same origin as request #{source.inspect}"
           end
    -
    -      raise Violation, "Redirect target #{target.inspect} does not have same origin as request (expected #{origin_of(source)})"
         end
     
         private
    +      def uri_same_origin?(target, source)
    +        target =~ QUALIFIED_URL_PATTERN && origin_of(target) == origin_of(source)
    +      rescue ArgumentError, URI::Error
    +        false
    +      end
    +
    +      def absolute_path?(target)
    +        target =~ URI::DEFAULT_PARSER.regexp[:ABS_PATH] && URI(target).host.nil? && !target.start_with?("//")
    +      rescue ArgumentError, URI::Error
    +        false
    +      end
    +
           def origin_of(url)
             uri = URI(url)
             "#{uri.scheme}://#{uri.host}:#{uri.port}"
    -      rescue ArgumentError
    -        nil
           end
       end
     end
    
  • test/controllers/callbacks_controller_test.rb+42 0 modified
    @@ -103,6 +103,48 @@ class GoogleSignIn::CallbacksControllerTest < ActionDispatch::IntegrationTest
         assert_response :bad_request
       end
     
    +  test "protecting against open redirects given a malformed URI" do
    +    post google_sign_in.authorization_url, params: { proceed_to: 'http://www.example.com\n\r@\n\revil.example.org/login' }
    +    assert_response :redirect
    +
    +    get google_sign_in.callback_url(code: '4/SgCpHSVW5-Cy', state: flash[:state])
    +    assert_response :bad_request
    +  end
    +
    +  test "rejects proceed_to paths if they are relative" do
    +    post google_sign_in.authorization_url, params: { proceed_to: 'login' }
    +    assert_response :redirect
    +
    +    get google_sign_in.callback_url(code: '4/SgCpHSVW5-Cy', state: flash[:state])
    +    assert_response :bad_request
    +  end
    +
    +  test "accepts proceed_to paths if they are absolute" do
    +    post google_sign_in.authorization_url, params: { proceed_to: '/login' }
    +    assert_response :redirect
    +
    +    stub_token_for '4/SgCpHSVW5-Cy', access_token: 'ya29.GlwIBo', id_token: 'eyJhbGciOiJSUzI'
    +
    +    get google_sign_in.callback_url(code: '4/SgCpHSVW5-Cy', state: flash[:state])
    +    assert_redirected_to 'http://www.example.com/login'
    +  end
    +
    +  test "protecting against open redirects given a double-slash net path" do
    +    post google_sign_in.authorization_url, params: { proceed_to: '//evil.example.org' }
    +    assert_response :redirect
    +
    +    get google_sign_in.callback_url(code: '4/SgCpHSVW5-Cy', state: flash[:state])
    +    assert_response :bad_request
    +  end
    +
    +  test "protecting against open redirects given a triple-slash net path" do
    +    post google_sign_in.authorization_url, params: { proceed_to: '///evil.example.org' }
    +    assert_response :redirect
    +
    +    get google_sign_in.callback_url(code: '4/SgCpHSVW5-Cy', state: flash[:state])
    +    assert_response :bad_request
    +  end
    +
       test "receiving no proceed_to URL" do
         get google_sign_in.callback_url(code: '4/SgCpHSVW5-Cy', state: 'invalid')
         assert_response :bad_request
    
  • test/models/redirect_protector_test.rb+33 1 modified
    @@ -44,9 +44,41 @@ class GoogleSignIn::RedirectProtectorTest < ActiveSupport::TestCase
         end
       end
     
    -  test "allows path target" do
    +  test "disallows relative path target" do
    +    assert_raises GoogleSignIn::RedirectProtector::Violation do
    +      GoogleSignIn::RedirectProtector.ensure_same_origin 'callback', 'https://basecamp.com'
    +    end
    +  end
    +
    +  test "allows absolute path target" do
         assert_nothing_raised do
           GoogleSignIn::RedirectProtector.ensure_same_origin '/callback', 'https://basecamp.com'
         end
       end
    +
    +  test "disallows double-slash path target" do
    +    assert_raises GoogleSignIn::RedirectProtector::Violation do
    +      GoogleSignIn::RedirectProtector.ensure_same_origin '//evil.example.org', 'https://basecamp.com'
    +    end
    +  end
    +
    +  test "disallows triple-slash path target" do
    +    assert_raises GoogleSignIn::RedirectProtector::Violation do
    +      GoogleSignIn::RedirectProtector.ensure_same_origin '///evil.example.org', 'https://basecamp.com'
    +    end
    +  end
    +
    +  test "disallows invalid paths" do
    +    assert_raises GoogleSignIn::RedirectProtector::Violation do
    +      GoogleSignIn::RedirectProtector.ensure_same_origin '/a path with spaces is invalid', 'https://basecamp.com'
    +    end
    +
    +    assert_raises GoogleSignIn::RedirectProtector::Violation do
    +      GoogleSignIn::RedirectProtector.ensure_same_origin '/path#with-fragment', 'https://basecamp.com'
    +    end
    +
    +    assert_raises GoogleSignIn::RedirectProtector::Violation do
    +      GoogleSignIn::RedirectProtector.ensure_same_origin '/path?with=query', 'https://basecamp.com'
    +    end
    +  end
     end
    

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

7

News mentions

0

No linked articles in our index yet.