diff options
author | Yassen Damyanov <yd@itlabs.bg> | 2022-09-22 12:12:28 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-09-23 17:27:30 -0400 |
commit | 3333c6623fa45bcbc7fabd061184a79b7b7f2fa6 (patch) | |
tree | 6c262c52683c544470d68a0ae40c5c0ed16b1722 /test/engine/test_parseconnect.py | |
parent | d50bbd56740f86bb363b405f7d8e5df9667bb4e3 (diff) | |
download | sqlalchemy-3333c6623fa45bcbc7fabd061184a79b7b7f2fa6.tar.gz |
Tighten password security by removing `URL.__str__`
For improved security, the :class:`_url.URL` object will now use password
obfuscation by default when ``str(url)`` is called. To stringify a URL with
cleartext password, the :meth:`_url.URL.render_as_string` may be used,
passing the :paramref:`_url.URL.render_as_string.hide_password` parameter
as ``False``. Thanks to our contributors for this pull request.
Fixes: #8567
Closes: #8563
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/8563
Pull-request-sha: d1f1127f753849eb70b8d6cc64badf34e1b9219b
Change-Id: If756c8073ff99ac83876d9833c8fe1d7c76211f9
Diffstat (limited to 'test/engine/test_parseconnect.py')
-rw-r--r-- | test/engine/test_parseconnect.py | 76 |
1 files changed, 59 insertions, 17 deletions
diff --git a/test/engine/test_parseconnect.py b/test/engine/test_parseconnect.py index 23be61aaf..f571b4bab 100644 --- a/test/engine/test_parseconnect.py +++ b/test/engine/test_parseconnect.py @@ -83,36 +83,57 @@ class URLTest(fixtures.TestBase): "E:/work/src/LEM/db/hello.db", None, ), u.database - eq_(str(u), text) + eq_(u.render_as_string(hide_password=False), text) def test_rfc1738_password(self): u = url.make_url("dbtype://user:pass word + other%3Awords@host/dbname") eq_(u.password, "pass word + other:words") - eq_(str(u), "dbtype://user:pass word + other%3Awords@host/dbname") + eq_(str(u), "dbtype://user:***@host/dbname") + eq_( + u.render_as_string(hide_password=False), + "dbtype://user:pass word + other%3Awords@host/dbname", + ) u = url.make_url( "dbtype://username:apples%2Foranges@hostspec/database" ) eq_(u.password, "apples/oranges") - eq_(str(u), "dbtype://username:apples%2Foranges@hostspec/database") + eq_(str(u), "dbtype://username:***@hostspec/database") + eq_( + u.render_as_string(hide_password=False), + "dbtype://username:apples%2Foranges@hostspec/database", + ) u = url.make_url( "dbtype://username:apples%40oranges%40%40@hostspec/database" ) eq_(u.password, "apples@oranges@@") + eq_(str(u), "dbtype://username:***@hostspec/database") eq_( - str(u), + u.render_as_string(hide_password=False), "dbtype://username:apples%40oranges%40%40@hostspec/database", ) u = url.make_url("dbtype://username%40:@hostspec/database") eq_(u.password, "") eq_(u.username, "username@") - eq_(str(u), "dbtype://username%40:@hostspec/database") + eq_( + # Do not reveal an empty password + str(u), + "dbtype://username%40:***@hostspec/database", + ) + eq_( + u.render_as_string(hide_password=False), + "dbtype://username%40:@hostspec/database", + ) u = url.make_url("dbtype://username:pass%2Fword@hostspec/database") eq_(u.password, "pass/word") - eq_(str(u), "dbtype://username:pass%2Fword@hostspec/database") + eq_(str(u), "dbtype://username:***@hostspec/database") + eq_( + u.render_as_string(hide_password=False), + "dbtype://username:pass%2Fword@hostspec/database", + ) def test_password_custom_obj(self): class SecurePassword(str): @@ -128,58 +149,76 @@ class URLTest(fixtures.TestBase): ) eq_(u.password, "secured_password") - eq_(str(u), "dbtype://x:secured_password@localhost") + eq_( + u.render_as_string(hide_password=False), + "dbtype://x:secured_password@localhost", + ) # test in-place modification sp.value = "new_secured_password" eq_(u.password, sp) - eq_(str(u), "dbtype://x:new_secured_password@localhost") + eq_( + u.render_as_string(hide_password=False), + "dbtype://x:new_secured_password@localhost", + ) u = u.set(password="hi") eq_(u.password, "hi") - eq_(str(u), "dbtype://x:hi@localhost") + eq_(u.render_as_string(hide_password=False), "dbtype://x:hi@localhost") u = u._replace(password=None) is_(u.password, None) - eq_(str(u), "dbtype://x@localhost") + eq_(u.render_as_string(hide_password=False), "dbtype://x@localhost") def test_query_string(self): u = url.make_url("dialect://user:pass@host/db?arg1=param1&arg2=param2") eq_(u.query, {"arg1": "param1", "arg2": "param2"}) - eq_(str(u), "dialect://user:pass@host/db?arg1=param1&arg2=param2") + eq_( + u.render_as_string(hide_password=False), + "dialect://user:pass@host/db?arg1=param1&arg2=param2", + ) u = url.make_url("dialect://user:pass@host/?arg1=param1&arg2=param2") eq_(u.query, {"arg1": "param1", "arg2": "param2"}) eq_(u.database, "") - eq_(str(u), "dialect://user:pass@host/?arg1=param1&arg2=param2") + eq_( + u.render_as_string(hide_password=False), + "dialect://user:pass@host/?arg1=param1&arg2=param2", + ) u = url.make_url("dialect://user:pass@host?arg1=param1&arg2=param2") eq_(u.query, {"arg1": "param1", "arg2": "param2"}) eq_(u.database, None) - eq_(str(u), "dialect://user:pass@host?arg1=param1&arg2=param2") + eq_( + u.render_as_string(hide_password=False), + "dialect://user:pass@host?arg1=param1&arg2=param2", + ) u = url.make_url( "dialect://user:pass@host:450?arg1=param1&arg2=param2" ) eq_(u.port, 450) eq_(u.query, {"arg1": "param1", "arg2": "param2"}) - eq_(str(u), "dialect://user:pass@host:450?arg1=param1&arg2=param2") + eq_( + u.render_as_string(hide_password=False), + "dialect://user:pass@host:450?arg1=param1&arg2=param2", + ) u = url.make_url( "dialect://user:pass@host/db?arg1=param1&arg2=param2&arg2=param3" ) eq_(u.query, {"arg1": "param1", "arg2": ("param2", "param3")}) eq_( - str(u), + u.render_as_string(hide_password=False), "dialect://user:pass@host/db?arg1=param1&arg2=param2&arg2=param3", ) test_url = "dialect://user:pass@host/db?arg1%3D=param1&arg2=param+2" u = url.make_url(test_url) eq_(u.query, {"arg1=": "param1", "arg2": "param 2"}) - eq_(str(u), test_url) + eq_(u.render_as_string(hide_password=False), test_url) def test_comparison(self): common_url = ( @@ -727,7 +766,10 @@ class CreateEngineTest(fixtures.TestBase): assert e.url.drivername == e2.url.drivername == "mysql+mysqldb" assert e.url.username == e2.url.username == "scott" assert e2.url is u - assert str(u) == "mysql+mysqldb://scott:tiger@localhost/test" + eq_( + u.render_as_string(hide_password=False), + "mysql+mysqldb://scott:tiger@localhost/test", + ) assert repr(u) == "mysql+mysqldb://scott:***@localhost/test" assert repr(e) == "Engine(mysql+mysqldb://scott:***@localhost/test)" assert repr(e2) == "Engine(mysql+mysqldb://scott:***@localhost/test)" |