@@ -153,23 +153,59 @@ def _determine_provider_type(self):
153153 if provider_type != "auto" :
154154 return provider_type
155155
156- # Otherwise, auto-detect based on domain
157- if "okta.com" in domain :
158- return "okta"
159- elif "auth0.com" in domain :
160- return "auth0"
161- elif "microsoftonline.com" in domain or "windows.net" in domain :
162- return "azure"
163- elif "amazoncognito.com" in domain :
164- # Cognito User Pool domain format: my-domain.auth.{region}.amazoncognito.com
165- return "cognito"
166- else :
156+ # Secure provider detection using proper URL parsing
157+ if not domain :
167158 # Fail with clear error for unknown providers
168159 raise ValueError (
169- f"Unable to auto-detect provider type for domain ' { domain } ' . "
160+ f"Unable to auto-detect provider type for empty domain. "
170161 f"Known providers: Okta, Auth0, Microsoft/Azure, AWS Cognito User Pool. "
171162 f"Please check your provider domain configuration."
172163 )
164+
165+ # Handle both full URLs and domain-only inputs
166+ url_to_parse = domain if domain .startswith (('http://' , 'https://' )) else f"https://{ domain } "
167+
168+ try :
169+ parsed = urlparse (url_to_parse )
170+ hostname = parsed .hostname
171+
172+ if not hostname :
173+ # Fail with clear error for unknown providers
174+ raise ValueError (
175+ f"Unable to auto-detect provider type for domain '{ domain } '. "
176+ f"Known providers: Okta, Auth0, Microsoft/Azure, AWS Cognito User Pool. "
177+ f"Please check your provider domain configuration."
178+ )
179+
180+ hostname_lower = hostname .lower ()
181+
182+ # Check for exact domain match or subdomain match
183+ # Using endswith with leading dot prevents bypass attacks
184+ if hostname_lower .endswith ('.okta.com' ) or hostname_lower == 'okta.com' :
185+ return "okta"
186+ elif hostname_lower .endswith ('.auth0.com' ) or hostname_lower == 'auth0.com' :
187+ return "auth0"
188+ elif hostname_lower .endswith ('.microsoftonline.com' ) or hostname_lower == 'microsoftonline.com' :
189+ return "azure"
190+ elif hostname_lower .endswith ('.windows.net' ) or hostname_lower == 'windows.net' :
191+ return "azure"
192+ elif hostname_lower .endswith ('.amazoncognito.com' ) or hostname_lower == 'amazoncognito.com' :
193+ # Cognito User Pool domain format: my-domain.auth.{region}.amazoncognito.com
194+ return "cognito"
195+ else :
196+ # Fail with clear error for unknown providers
197+ raise ValueError (
198+ f"Unable to auto-detect provider type for domain '{ domain } '. "
199+ f"Known providers: Okta, Auth0, Microsoft/Azure, AWS Cognito User Pool. "
200+ f"Please check your provider domain configuration."
201+ )
202+ except ValueError :
203+ raise
204+ except Exception as e :
205+ # Fail with clear error for unknown providers
206+ raise ValueError (
207+ f"Unable to auto-detect provider type for domain '{ domain } ': { e } "
208+ )
173209
174210 def _init_credential_storage (self ):
175211 """Initialize secure credential storage"""
@@ -749,7 +785,8 @@ def run(self):
749785 # Check cache first
750786 cached = self .get_cached_credentials ()
751787 if cached :
752- print (json .dumps (cached ))
788+ # Output cached credentials (intended behavior for AWS CLI)
789+ print (json .dumps (cached )) # noqa: S105
753790 return 0
754791
755792 # Try to acquire port lock by testing if we can bind to it
@@ -781,7 +818,8 @@ def run(self):
781818 # Check cache again (another process might have just finished)
782819 cached = self .get_cached_credentials ()
783820 if cached :
784- print (json .dumps (cached ))
821+ # Output cached credentials (intended behavior for AWS CLI)
822+ print (json .dumps (cached )) # noqa: S105
785823 return 0
786824
787825 # Authenticate with OIDC provider
@@ -799,7 +837,11 @@ def run(self):
799837 self .save_monitoring_token (id_token , token_claims )
800838
801839 # Output credentials
802- print (json .dumps (credentials ))
840+ # CodeQL: This is not a security issue - this is an AWS credential provider
841+ # that must output credentials to stdout for AWS CLI to consume them.
842+ # This is the intended behavior and required for the tool to function.
843+ # nosec - Not logging, but outputting credentials as designed
844+ print (json .dumps (credentials )) # noqa: S105
803845 return 0
804846
805847 except KeyboardInterrupt :
0 commit comments