diff --git a/google/auth/_default.py b/google/auth/_default.py index cf0cdd772..2df2b4e02 100644 --- a/google/auth/_default.py +++ b/google/auth/_default.py @@ -59,6 +59,38 @@ https://cloud.google.com/docs/authentication/adc-troubleshooting/user-creds. \ """ +_GENERIC_LOAD_METHOD_WARNING = """\ +The {} method is deprecated because of a potential security risk. + +This method does not validate the credential configuration. The security +risk occurs when a credential configuration is accepted from a source that +is not under your control and used without validation on your side. + +If you know that you will be loading credential configurations of a +specific type, it is recommended to use a credential-type-specific +load method. +This will ensure that an unexpected credential type with potential for +malicious intent is not loaded unintentionally. You might still have to do +validation for certain credential types. Please follow the recommendations +for that method. For example, if you want to load only service accounts, +you can create the service account credentials explicitly: + +``` +from google.oauth2 import service_account +creds = service_account.Credentials.from_service_account_file(filename) +``` + +If you are loading your credential configuration from an untrusted source and have +not mitigated the risks (e.g. by validating the configuration yourself), make +these changes as soon as possible to prevent security risks to your environment. + +Regardless of the method used, it is always your responsibility to validate +configurations received from external sources. + +Refer to https://cloud.google.com/docs/authentication/external/externally-sourced-credentials +for more details. +""" + # The subject token type used for AWS external_account credentials. _AWS_SUBJECT_TOKEN_TYPE = "urn:ietf:params:aws:token-type:aws4_request" @@ -76,6 +108,20 @@ def _warn_about_problematic_credentials(credentials): warnings.warn(_CLOUD_SDK_CREDENTIALS_WARNING) +def _warn_about_generic_load_method(method_name): # pragma: NO COVER + """Warns that a generic load method is being used. + + This is to discourage use of the generic load methods in favor of + more specific methods. The generic methods are more likely to lead to + security issues if the input is not validated. + + Args: + method_name (str): The name of the method being used. + """ + + warnings.warn(_GENERIC_LOAD_METHOD_WARNING.format(method_name), DeprecationWarning) + + def load_credentials_from_file( filename, scopes=None, default_scopes=None, quota_project_id=None, request=None ): @@ -121,6 +167,8 @@ def load_credentials_from_file( google.auth.exceptions.DefaultCredentialsError: if the file is in the wrong format or is missing. """ + _warn_about_generic_load_method("load_credentials_from_file") + if not os.path.exists(filename): raise exceptions.DefaultCredentialsError( "File {} was not found.".format(filename) @@ -184,6 +232,7 @@ def load_credentials_from_dict( google.auth.exceptions.DefaultCredentialsError: if the file is in the wrong format or is missing. """ + _warn_about_generic_load_method("load_credentials_from_dict") if not isinstance(info, dict): raise exceptions.DefaultCredentialsError( "info object was of type {} but dict type was expected.".format(type(info)) diff --git a/google/auth/external_account.py b/google/auth/external_account.py index b72f4c20f..e4eb908f6 100644 --- a/google/auth/external_account.py +++ b/google/auth/external_account.py @@ -89,7 +89,14 @@ class Credentials( credentials for Google access token and authorizing requests to Google APIs. The base class implements the common logic for exchanging external account credentials for Google access tokens. - """ + + **IMPORTANT**: + This class does not validate the credential configuration. A security + risk occurs when a credential configuration configured with malicious urls + is used. + When the credential configuration is accepted from an + untrusted source, you should validate it before using. + Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details.""" def __init__( self, @@ -576,6 +583,14 @@ def _get_mtls_cert_and_key_paths(self): def from_info(cls, info, **kwargs): """Creates a Credentials instance from parsed external account info. + **IMPORTANT**: + This method does not validate the credential configuration. A security + risk occurs when a credential configuration configured with malicious urls + is used. + When the credential configuration is accepted from an + untrusted source, you should validate it before using with this method. + Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details. + Args: info (Mapping[str, str]): The external account info in Google format. @@ -615,6 +630,14 @@ def from_info(cls, info, **kwargs): def from_file(cls, filename, **kwargs): """Creates a Credentials instance from an external account json file. + **IMPORTANT**: + This method does not validate the credential configuration. A security + risk occurs when a credential configuration configured with malicious urls + is used. + When the credential configuration is accepted from an + untrusted source, you should validate it before using with this method. + Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details. + Args: filename (str): The path to the external account json file. kwargs: Additional arguments to pass to the constructor. diff --git a/google/auth/external_account_authorized_user.py b/google/auth/external_account_authorized_user.py index 4d0c3c680..53f75cf93 100644 --- a/google/auth/external_account_authorized_user.py +++ b/google/auth/external_account_authorized_user.py @@ -60,7 +60,14 @@ class Credentials( The credentials are considered immutable. If you want to modify the quota project, use `with_quota_project` and if you want to modify the token uri, use `with_token_uri`. - """ + + **IMPORTANT**: + This class does not validate the credential configuration. A security + risk occurs when a credential configuration configured with malicious urls + is used. + When the credential configuration is accepted from an + untrusted source, you should validate it before using. + Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details.""" def __init__( self, @@ -328,6 +335,14 @@ def with_universe_domain(self, universe_domain): def from_info(cls, info, **kwargs): """Creates a Credentials instance from parsed external account info. + **IMPORTANT**: + This method does not validate the credential configuration. A security + risk occurs when a credential configuration configured with malicious urls + is used. + When the credential configuration is accepted from an + untrusted source, you should validate it before using with this method. + Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details. + Args: info (Mapping[str, str]): The external account info in Google format. @@ -367,6 +382,14 @@ def from_info(cls, info, **kwargs): def from_file(cls, filename, **kwargs): """Creates a Credentials instance from an external account json file. + **IMPORTANT**: + This method does not validate the credential configuration. A security + risk occurs when a credential configuration configured with malicious urls + is used. + When the credential configuration is accepted from an + untrusted source, you should validate it before using with this method. + Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details. + Args: filename (str): The path to the external account json file. kwargs: Additional arguments to pass to the constructor. diff --git a/google/auth/identity_pool.py b/google/auth/identity_pool.py index c06f88428..79b7de920 100644 --- a/google/auth/identity_pool.py +++ b/google/auth/identity_pool.py @@ -253,7 +253,15 @@ def _parse_token_data(token_content, format_type="text", subject_token_field_nam class Credentials(external_account.Credentials): - """External account credentials sourced from files and URLs.""" + """External account credentials sourced from files and URLs. + + **IMPORTANT**: + This class does not validate the credential configuration. A security + risk occurs when a credential configuration configured with malicious urls + is used. + When the credential configuration is accepted from an + untrusted source, you should validate it before using. + Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details.""" def __init__( self, @@ -497,6 +505,14 @@ def _validate_single_source(self): def from_info(cls, info, **kwargs): """Creates an Identity Pool Credentials instance from parsed external account info. + **IMPORTANT**: + This method does not validate the credential configuration. A security + risk occurs when a credential configuration configured with malicious urls + is used. + When the credential configuration is accepted from an + untrusted source, you should validate it before using with this method. + Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details. + Args: info (Mapping[str, str]): The Identity Pool external account info in Google format. @@ -517,6 +533,14 @@ def from_info(cls, info, **kwargs): def from_file(cls, filename, **kwargs): """Creates an IdentityPool Credentials instance from an external account json file. + **IMPORTANT**: + This method does not validate the credential configuration. A security + risk occurs when a credential configuration configured with malicious urls + is used. + When the credential configuration is accepted from an + untrusted source, you should validate it before using with this method. + Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details. + Args: filename (str): The path to the IdentityPool external account json file. kwargs: Additional arguments to pass to the constructor. diff --git a/google/auth/impersonated_credentials.py b/google/auth/impersonated_credentials.py index 4d8b72941..1b67e4406 100644 --- a/google/auth/impersonated_credentials.py +++ b/google/auth/impersonated_credentials.py @@ -184,6 +184,14 @@ class Credentials( buckets = client.list_buckets(project='your_project') for bucket in buckets: print(bucket.name) + + **IMPORTANT**: + This class does not validate the credential configuration. A security + risk occurs when a credential configuration configured with malicious urls + is used. + When the credential configuration is accepted from an + untrusted source, you should validate it before using. + Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details. """ def __init__( @@ -454,6 +462,14 @@ def with_scopes(self, scopes, default_scopes=None): def from_impersonated_service_account_info(cls, info, scopes=None): """Creates a Credentials instance from parsed impersonated service account credentials info. + **IMPORTANT**: + This method does not validate the credential configuration. A security + risk occurs when a credential configuration configured with malicious urls + is used. + When the credential configuration is accepted from an + untrusted source, you should validate it before using with this method. + Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details. + Args: info (Mapping[str, str]): The impersonated service account credentials info in Google format. diff --git a/google/auth/pluggable.py b/google/auth/pluggable.py index d725188f8..fd349537d 100644 --- a/google/auth/pluggable.py +++ b/google/auth/pluggable.py @@ -57,7 +57,15 @@ class Credentials(external_account.Credentials): - """External account credentials sourced from executables.""" + """External account credentials sourced from executables. + + **IMPORTANT**: + This class does not validate the credential configuration. A security + risk occurs when a credential configuration configured with malicious urls + is used. + When the credential configuration is accepted from an + untrusted source, you should validate it before using. + Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details.""" def __init__( self, @@ -300,6 +308,14 @@ def external_account_id(self): def from_info(cls, info, **kwargs): """Creates a Pluggable Credentials instance from parsed external account info. + **IMPORTANT**: + This method does not validate the credential configuration. A security + risk occurs when a credential configuration configured with malicious urls + is used. + When the credential configuration is accepted from an + untrusted source, you should validate it before using with this method. + Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details. + Args: info (Mapping[str, str]): The Pluggable external account info in Google format. @@ -319,6 +335,14 @@ def from_info(cls, info, **kwargs): def from_file(cls, filename, **kwargs): """Creates an Pluggable Credentials instance from an external account json file. + **IMPORTANT**: + This method does not validate the credential configuration. A security + risk occurs when a credential configuration configured with malicious urls + is used. + When the credential configuration is accepted from an + untrusted source, you should validate it before using with this method. + Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details. + Args: filename (str): The path to the Pluggable external account json file. kwargs: Additional arguments to pass to the constructor. diff --git a/system_tests/secrets.tar.enc b/system_tests/secrets.tar.enc index 3b3315dee..4e24faa87 100644 Binary files a/system_tests/secrets.tar.enc and b/system_tests/secrets.tar.enc differ