Skip to content

Commit 0c58649

Browse files
committed
Validate OIDC allowed hosts before cache reuse
1 parent 0adf6df commit 0c58649

4 files changed

Lines changed: 46 additions & 6 deletions

File tree

pymongo/asynchronous/auth_oidc.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@
4949
def _get_authenticator(
5050
credentials: MongoCredential, address: tuple[str, int]
5151
) -> _OIDCAuthenticator:
52-
if credentials.cache.data:
53-
return credentials.cache.data
54-
5552
# Extract values.
5653
principal_name = credentials.username
5754
properties = credentials.mechanism_properties
@@ -70,6 +67,9 @@ def _get_authenticator(
7067
f"Refusing to connect to {address[0]}, which is not in authOIDCAllowedHosts: {allowed_hosts}"
7168
)
7269

70+
if credentials.cache.data:
71+
return credentials.cache.data
72+
7373
# Get or create the cache data.
7474
credentials.cache.data = _OIDCAuthenticator(username=principal_name, properties=properties)
7575
return credentials.cache.data

pymongo/synchronous/auth_oidc.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@
4949
def _get_authenticator(
5050
credentials: MongoCredential, address: tuple[str, int]
5151
) -> _OIDCAuthenticator:
52-
if credentials.cache.data:
53-
return credentials.cache.data
54-
5552
# Extract values.
5653
principal_name = credentials.username
5754
properties = credentials.mechanism_properties
@@ -70,6 +67,9 @@ def _get_authenticator(
7067
f"Refusing to connect to {address[0]}, which is not in authOIDCAllowedHosts: {allowed_hosts}"
7168
)
7269

70+
if credentials.cache.data:
71+
return credentials.cache.data
72+
7373
# Get or create the cache data.
7474
credentials.cache.data = _OIDCAuthenticator(username=principal_name, properties=properties)
7575
return credentials.cache.data

test/asynchronous/test_auth_oidc.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,26 @@ async def fail_point(self, command_args):
117117
await client.close()
118118

119119

120+
class TestOIDCAllowedHostsCache(unittest.TestCase):
121+
class HumanCallback(OIDCCallback):
122+
def fetch(self, context):
123+
return OIDCCallbackResult(access_token="token")
124+
125+
def test_allowed_hosts_checked_before_cached_authenticator_reuse(self):
126+
props = {
127+
"OIDC_HUMAN_CALLBACK": self.HumanCallback(),
128+
"ALLOWED_HOSTS": ["good.example.com"],
129+
}
130+
extra = {"authmechanismproperties": props}
131+
credentials = _build_credentials_tuple("MONGODB-OIDC", None, "user", None, extra, "test")
132+
133+
authenticator = _get_authenticator(credentials, ("good.example.com", 27017))
134+
self.assertIs(authenticator, credentials.cache.data)
135+
136+
with self.assertRaisesRegex(ConfigurationError, "evil.example.com"):
137+
_get_authenticator(credentials, ("evil.example.com", 27017))
138+
139+
120140
class TestAuthOIDCHuman(OIDCTestBase):
121141
uri: str
122142

test/test_auth_oidc.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,26 @@ def fail_point(self, command_args):
117117
client.close()
118118

119119

120+
class TestOIDCAllowedHostsCache(unittest.TestCase):
121+
class HumanCallback(OIDCCallback):
122+
def fetch(self, context):
123+
return OIDCCallbackResult(access_token="token")
124+
125+
def test_allowed_hosts_checked_before_cached_authenticator_reuse(self):
126+
props = {
127+
"OIDC_HUMAN_CALLBACK": self.HumanCallback(),
128+
"ALLOWED_HOSTS": ["good.example.com"],
129+
}
130+
extra = {"authmechanismproperties": props}
131+
credentials = _build_credentials_tuple("MONGODB-OIDC", None, "user", None, extra, "test")
132+
133+
authenticator = _get_authenticator(credentials, ("good.example.com", 27017))
134+
self.assertIs(authenticator, credentials.cache.data)
135+
136+
with self.assertRaisesRegex(ConfigurationError, "evil.example.com"):
137+
_get_authenticator(credentials, ("evil.example.com", 27017))
138+
139+
120140
class TestAuthOIDCHuman(OIDCTestBase):
121141
uri: str
122142

0 commit comments

Comments
 (0)