启用或停用电子邮件枚举保护

本指南介绍了电子邮件枚举保护功能,并说明了如何启用和停用该功能。如果您是在 2023 年 9 月 15 日或之后创建的项目,系统会默认启用电子邮件枚举保护。

概览

电子邮件枚举是一种暴力破解类型,恶意操作者通过将电子邮件地址传递给 API 并检查响应,尝试猜测或确认系统中的用户。

如果没有电子邮件枚举保护,Identity Platform 会返回可用于电子邮件枚举攻击的信息:

  • 尝试使用系统中不存在的电子邮件地址登录。Identity Platform 返回 EMAIL_NOT_FOUND 错误。

  • 尝试使用系统中已存在的电子邮件地址进行注册。Identity Platform 返回 EMAIL_EXISTS 错误。

您可以使用 Identity Platform 的电子邮件枚举保护功能来保护应用中的用户帐号免受这些攻击。

启用电子邮件枚举保护后,您的项目将具有以下行为:

  • fetchSignInForEmail API 将失败。在 SDK 版本 22.3.0 (Android)、10.18.0 (iOS) 和 10.6.0 (Web) 之前的版本中,将经过身份验证的匿名用户关联到电子邮件地址也无法实现。

  • 在所有平台上调用 createAuthUri REST API 或 fetchSignInMethodsForEmail 客户端 SDK 方法时,不再返回指定电子邮件地址的登录方法列表。

  • 用户必须先验证新地址,然后才能更改其电子邮件地址。例如,您无法再在所有平台上使用 update REST API、setAccountInfo REST API 或 updateEmail 客户端 SDK 方法更改用户的电子邮件地址。

    您可以改用 verifyBeforeUpdateEmail(适用于 Web 和 Android)或 sendEmailVerification(beforeUpdatingEmail:)(适用于 iOS)。

  • 您无法再使用 setAccountInfo REST API 将电子邮件地址/密码提供方与现有用户帐号关联。在任何平台上,您无法再将 linkWithCredential 客户端 SDK 方法与 EmailAuthCredential 搭配使用。请改用 REST API signUp,在 idToken 字段中传递用户的 ID 令牌以及要关联的 emailpassword 字段。

  • 移除了电子邮件验证流程的错误响应,例如通过以下方式启动的错误响应:调用 sendOobCode REST API(请求类型为 VERIFY_AND_CHANGE_EMAILPASSWORD_RESET),以及调用 verifyBeforeUpdateEmail(适用于 Web 和 Android)、sendEmailVerification(beforeUpdatingEmail:)(适用于 iOS)或 sendPasswordResetEmail 客户端 SDK 方法(适用于所有平台)。

    当您请求重设密码时,只有电子邮件地址存在时,系统才会发送验证电子邮件;当您请求更改电子邮件地址时,只有电子邮件地址尚不存在时,系统才会发送验证电子邮件。在这两种情况下,系统不会显示表明电子邮件未发送的具体错误消息。

    我们建议您不允许没有电子邮件验证流程的用户注册。

  • 无效登录情况会返回 INVALID_LOGIN_CREDENTIALS 错误响应。无效注册情况会继续返回 EMAIL_EXISTS 错误,请参阅下一部分中的建议。

如果您的应用依赖于电子邮件枚举保护机制所更改的任何行为,您目前可以将其停用。不过,我们不建议您长期采用这种做法;请参阅下一部分。

安全建议

实施帐号盗用攻击的最常见方法之一是使用泄露或容易猜到的凭据执行凭据填充攻击。电子邮件枚举还可用于获取有关用户的敏感信息,或针对用户执行钓鱼式攻击。出于这些原因,Google 建议您使用电子邮件枚举保护功能来保护您的应用免受此类攻击。

  • 如果您是在 2023 年 9 月 15 日或之后创建的项目,系统会默认启用电子邮件枚举保护。我们建议您启用电子邮件枚举保护,并且不要依赖本指南前面部分列出的任何行为。

  • 如果您的项目是在 2023 年 9 月 15 日之前创建的,则系统不会自动启用电子邮件枚举保护。

    如果您的应用不依赖于本指南前面描述的任何行为,我们建议您立即启用电子邮件枚举保护。

    如果您的应用依赖于上述任何行为,我们建议您停止这样做,并尽快启用电子邮件枚举保护。

除了使用电子邮件枚举保护功能之外,还应考虑采取措施防止滥用持续返回 EMAIL_EXISTS 错误的项目的注册端点。为此,您可以采用以下方法:

  • 启用 App Check
  • reCAPTCHA 集成到您的注册流程中。
  • 禁止使用电子邮件地址和密码或电子邮件链接登录,而应改用 Google 登录等替代方法。

启用电子邮件枚举保护

如需启用电子邮件枚举保护,请按以下步骤操作:

Firebase 控制台

  1. 在 Firebase 控制台中,转到 Firebase Auth 设置页面。

    转到 Firebase Authentication 设置

    1. 在导航窗格中,选择用户操作

    2. 选择电子邮件枚举保护(推荐)

  2. 点击保存

Node.js

  1. 安装 Admin SDK

  2. 如需启用电子邮件枚举保护,请使用以下某个方法:

    • 对于项目级保护:

      import { getAuth } from 'firebase-admin/auth';
      
      getAuth().projectConfigManager().updateProjectConfig(
        {
          emailPrivacyConfig: {
            enableImprovedEmailPrivacy: true,
          },
        }
      );
      
    • 为了在租户级别进行保护,请注意以下事项:

      import { getAuth } from 'firebase-admin/auth';
      
      getAuth().tenantConfigManager().updateTenant(TENANT_ID,
        {
          emailPrivacyConfig: {
            enableImprovedEmailPrivacy: true,
          },
        }
      );
      

      TENANT_ID 替换为您要启用电子邮件枚举保护的租户 ID。

REST

  1. 在 Google Cloud 控制台中,使用 gcloud auth print-access-token 命令输出项目 ID 的访问令牌:

    gcloud auth print-access-token --project=PROJECT_ID
    
  2. 使用 Identity Toolkit API 为您的项目 ID 启用电子邮件枚举保护:

    curl -X PATCH -d "{'emailPrivacyConfig':{'enableImprovedEmailPrivacy':true}}" \
        -H 'Authorization: Bearer ACCESS_TOKEN' \
        -H 'Content-Type: application/json' -H 'X-Goog-User-Project: PROJECT_ID' \
        "https://identitytoolkit.googleapis.com/admin/v2/projects/PROJECT_ID/config?updateMask=emailPrivacyConfig"
    

替换以下内容:

  • ACCESS_TOKEN:您之前生成的访问令牌
  • PROJECT_ID:您的项目 ID

停用电子邮件枚举保护

要停用电子邮件枚举保护,请按以下步骤操作:

Firebase 控制台

  1. 在 Firebase 控制台中,转到 Firebase Auth 设置页面。

    转到 Firebase Authentication 设置

    1. 在导航窗格中,选择用户操作

    2. 清除电子邮件枚举保护(推荐)

  2. 点击保存

Node.js

  1. 安装 Admin SDK

  2. 如需停用电子邮件枚举保护,请使用以下某个方法:

    • 对于项目级保护:

      import { getAuth } from 'firebase-admin/auth';
      
      getAuth().projectConfigManager().updateProjectConfig(
        {
          emailPrivacyConfig: {
            enableImprovedEmailPrivacy: false,
          },
        }
      );
      
    • 为了在租户级别进行保护,请注意以下事项:

      import { getAuth } from 'firebase-admin/auth';
      
      getAuth().tenantConfigManager().updateTenant(TENANT_ID,
        {
          emailPrivacyConfig: {
            enableImprovedEmailPrivacy: false,
          },
        }
      );
      

      TENANT_ID 替换为您要停用电子邮件枚举保护的租户 ID。

REST

  1. 在 Google Cloud 控制台中,使用 gcloud auth print-access-token 命令输出项目 ID 的访问令牌:

    gcloud auth print-access-token --project=PROJECT_ID
    
  2. 使用 Identity Toolkit API 停用电子邮件枚举保护:

    curl -X PATCH -d "{'emailPrivacyConfig':{'enableImprovedEmailPrivacy':false}}" \
        -H 'Authorization: Bearer ACCESS_TOKEN' \
        -H 'Content-Type: application/json' -H 'X-Goog-User-Project: PROJECT_ID' \
        "https://identitytoolkit.googleapis.com/admin/v2/projects/PROJECT_ID/config?updateMask=emailPrivacyConfig"
    

替换以下内容:

  • ACCESS_TOKEN:您之前生成的访问令牌
  • PROJECT_ID:您的项目 ID

错误响应示例

如果用户尝试使用错误的电子邮件地址或密码登录,或尝试使用系统中已存在的电子邮件地址进行注册,Identity Platform 会返回类似于以下内容的错误:

{
"code": "auth/internal-error",
"message": "{\"error\":{\"code\":400,\"message\":\"INVALID_LOGIN_CREDENTIALS\",\"errors\":[{\"message\":\"INVALID_LOGIN_CREDENTIALS\",\"domain\":\"global\",\"reason\":\"invalid\"}]}}"
}