summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2025-07-12 11:51:31 +0900
committergit <svn-admin@ruby-lang.org>2025-10-07 01:12:42 +0000
commitd0395bd0ead968e194e268f8c5f9db59d8831c02 (patch)
tree20b6590bcc56104fb02abaec13b17d854e10f6ce
parente3d4cb5de52332b475635949f48b5cc5620a9a5e (diff)
[ruby/uri] Clear user info totally at setting any of authority info
Fix CVE-2025-27221. https://hackerone.com/reports/3221142 https://github.com/ruby/uri/commit/5cec76b9e8
-rw-r--r--lib/uri/generic.rb10
-rw-r--r--test/uri/test_generic.rb15
2 files changed, 16 insertions, 9 deletions
diff --git a/lib/uri/generic.rb b/lib/uri/generic.rb
index d811c5b944..abdf5b4377 100644
--- a/lib/uri/generic.rb
+++ b/lib/uri/generic.rb
@@ -186,18 +186,18 @@ module URI
if arg_check
self.scheme = scheme
- self.userinfo = userinfo
self.hostname = host
self.port = port
+ self.userinfo = userinfo
self.path = path
self.query = query
self.opaque = opaque
self.fragment = fragment
else
self.set_scheme(scheme)
- self.set_userinfo(userinfo)
self.set_host(host)
self.set_port(port)
+ self.set_userinfo(userinfo)
self.set_path(path)
self.query = query
self.set_opaque(opaque)
@@ -511,7 +511,7 @@ module URI
user, password = split_userinfo(user)
end
@user = user
- @password = password if password
+ @password = password
[@user, @password]
end
@@ -522,7 +522,7 @@ module URI
# See also URI::Generic.user=.
#
def set_user(v)
- set_userinfo(v, @password)
+ set_userinfo(v, nil)
v
end
protected :set_user
@@ -639,6 +639,7 @@ module URI
def host=(v)
check_host(v)
set_host(v)
+ set_userinfo(nil)
v
end
@@ -729,6 +730,7 @@ module URI
def port=(v)
check_port(v)
set_port(v)
+ set_userinfo(nil)
port
end
diff --git a/test/uri/test_generic.rb b/test/uri/test_generic.rb
index c725116e96..94eea71b51 100644
--- a/test/uri/test_generic.rb
+++ b/test/uri/test_generic.rb
@@ -283,6 +283,9 @@ class URI::TestGeneric < Test::Unit::TestCase
u0 = URI.parse('http://new.example.org/path')
u1 = u.merge('//new.example.org/path')
assert_equal(u0, u1)
+ u0 = URI.parse('http://other@example.net')
+ u1 = u.merge('//other@example.net')
+ assert_equal(u0, u1)
end
def test_route
@@ -748,17 +751,18 @@ class URI::TestGeneric < Test::Unit::TestCase
def test_set_component
uri = URI.parse('http://foo:bar@baz')
assert_equal('oof', uri.user = 'oof')
- assert_equal('http://oof:bar@baz', uri.to_s)
+ assert_equal('http://oof@baz', uri.to_s)
assert_equal('rab', uri.password = 'rab')
assert_equal('http://oof:rab@baz', uri.to_s)
assert_equal('foo', uri.userinfo = 'foo')
- assert_equal('http://foo:rab@baz', uri.to_s)
+ assert_equal('http://foo@baz', uri.to_s)
assert_equal(['foo', 'bar'], uri.userinfo = ['foo', 'bar'])
assert_equal('http://foo:bar@baz', uri.to_s)
assert_equal(['foo'], uri.userinfo = ['foo'])
- assert_equal('http://foo:bar@baz', uri.to_s)
+ assert_equal('http://foo@baz', uri.to_s)
assert_equal('zab', uri.host = 'zab')
- assert_equal('http://foo:bar@zab', uri.to_s)
+ assert_equal('http://zab', uri.to_s)
+ uri.userinfo = ['foo', 'bar']
uri.port = ""
assert_nil(uri.port)
uri.port = "80"
@@ -768,7 +772,8 @@ class URI::TestGeneric < Test::Unit::TestCase
uri.port = " 080 "
assert_equal(80, uri.port)
assert_equal(8080, uri.port = 8080)
- assert_equal('http://foo:bar@zab:8080', uri.to_s)
+ assert_equal('http://zab:8080', uri.to_s)
+ uri = URI.parse('http://foo:bar@zab:8080')
assert_equal('/', uri.path = '/')
assert_equal('http://foo:bar@zab:8080/', uri.to_s)
assert_equal('a=1', uri.query = 'a=1')