CVE-2025-57821
Description
Basecamp's Google Sign-In adds Google sign-in to Rails applications. Prior to version 1.3.0, it is possible to craft a malformed URL that passes the "same origin" check, resulting in the user being redirected to another origin. Rails applications configured to store the flash information in a session cookie may be vulnerable, if this can be chained with an attack that allows injection of arbitrary data into the session cookie. This issue has been patched in version 1.3.0. If upgrading is not possible at this time, a way to mitigate the chained attack can be done by explicitly setting SameSite=Lax or SameSite=Strict on the application session cookie.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
google_sign_inRubyGems | < 1.3.0 | 1.3.0 |
Affected products
1- Range: v0.1, v0.1.1, v0.1.2, …
Patches
3e206b0af5035Merge pull request #74 from basecamp/flavorjones/gemspec-files
1 file changed · +1 −2
google_sign_in.gemspec+1 −2 modified@@ -13,6 +13,5 @@ Gem::Specification.new do |s| s.add_dependency 'google-id-token', '>= 1.4.0' s.add_dependency 'oauth2', '>= 1.4.0' - s.files = `git ls-files`.split("\n") - s.test_files = `git ls-files -- test/*`.split("\n") + s.files = Dir["{app,config,lib}/**/*", "MIT-LICENSE", "README.md", "SECURITY.md"] end
859036512012Merge pull request #73 from basecamp/flavorjones/fix-url-check
2 files changed · +17 −2
lib/google_sign_in/redirect_protector.rb+5 −2 modified@@ -9,9 +9,12 @@ class Violation < StandardError; end QUALIFIED_URL_PATTERN = /\A#{URI::DEFAULT_PARSER.make_regexp}\z/ def ensure_same_origin(target, source) - if target.blank? || (target =~ QUALIFIED_URL_PATTERN && origin_of(target) != origin_of(source)) - raise Violation, "Redirect target #{target.inspect} does not have same origin as request (expected #{origin_of(source)})" + if (target =~ QUALIFIED_URL_PATTERN && origin_of(target) == origin_of(source)) || + target =~ URI::DEFAULT_PARSER.regexp[:ABS_PATH] + return end + + raise Violation, "Redirect target #{target.inspect} does not have same origin as request (expected #{origin_of(source)})" end private
test/models/redirect_protector_test.rb+12 −0 modified@@ -8,6 +8,18 @@ class GoogleSignIn::RedirectProtectorTest < ActiveSupport::TestCase end end + test "disallows URL target that is not a valid URL" do + assert_raises GoogleSignIn::RedirectProtector::Violation do + GoogleSignIn::RedirectProtector.ensure_same_origin 'https://basecamp.com\n\r@\n\revil.com', 'https://basecamp.com' + end + end + + test "disallows URL target that is blank" do + assert_raises GoogleSignIn::RedirectProtector::Violation do + GoogleSignIn::RedirectProtector.ensure_same_origin '', 'https://basecamp.com' + end + end + test "disallows URL target with different port than source" do assert_raises GoogleSignIn::RedirectProtector::Violation do GoogleSignIn::RedirectProtector.ensure_same_origin 'https://basecamp.com:10443', 'https://basecamp.com'
a0548a604fb1Prevent redirects to malformed URLs
2 files changed · +17 −2
lib/google_sign_in/redirect_protector.rb+5 −2 modified@@ -9,9 +9,12 @@ class Violation < StandardError; end QUALIFIED_URL_PATTERN = /\A#{URI::DEFAULT_PARSER.make_regexp}\z/ def ensure_same_origin(target, source) - if target.blank? || (target =~ QUALIFIED_URL_PATTERN && origin_of(target) != origin_of(source)) - raise Violation, "Redirect target #{target.inspect} does not have same origin as request (expected #{origin_of(source)})" + if (target =~ QUALIFIED_URL_PATTERN && origin_of(target) == origin_of(source)) || + target =~ URI::DEFAULT_PARSER.regexp[:ABS_PATH] + return end + + raise Violation, "Redirect target #{target.inspect} does not have same origin as request (expected #{origin_of(source)})" end private
test/models/redirect_protector_test.rb+12 −0 modified@@ -8,6 +8,18 @@ class GoogleSignIn::RedirectProtectorTest < ActiveSupport::TestCase end end + test "disallows URL target that is not a valid URL" do + assert_raises GoogleSignIn::RedirectProtector::Violation do + GoogleSignIn::RedirectProtector.ensure_same_origin 'https://basecamp.com\n\r@\n\revil.com', 'https://basecamp.com' + end + end + + test "disallows URL target that is blank" do + assert_raises GoogleSignIn::RedirectProtector::Violation do + GoogleSignIn::RedirectProtector.ensure_same_origin '', 'https://basecamp.com' + end + end + test "disallows URL target with different port than source" do assert_raises GoogleSignIn::RedirectProtector::Violation do GoogleSignIn::RedirectProtector.ensure_same_origin 'https://basecamp.com:10443', 'https://basecamp.com'
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
8- github.com/advisories/GHSA-7pwc-wh6m-44q3ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-57821ghsaADVISORY
- github.com/basecamp/google_sign_in/commit/85903651201257d4f14b97d4582e6d968ac32f15nvdWEB
- github.com/basecamp/google_sign_in/commit/a0548a604fb17e4eb1a57029f0d87e34e8499623ghsaWEB
- github.com/basecamp/google_sign_in/pull/73nvdWEB
- github.com/basecamp/google_sign_in/releases/tag/v1.3.0nvdWEB
- github.com/basecamp/google_sign_in/security/advisories/GHSA-7pwc-wh6m-44q3nvdWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/google_sign_in/CVE-2025-57821.ymlghsaWEB
News mentions
0No linked articles in our index yet.