在客户通信中包含标记化电子邮件地址作为 URL 参数是不好的做法吗?

问题描述 投票:0回答:1

我目前遇到一个问题,用户注册时使用的电子邮件地址与他们签出时使用的电子邮件地址不同(他们的数据通过电子邮件地址存储在我们的后端)。但是,我不想在结帐之外阻止注册,因为(截至目前)我还允许在购买产品之前进行注册。我可以在结账时自动为用户生成一个帐户,但如果他们稍后使用另一封电子邮件注册,这不会改变任何事情。

我目前的想法是,我将添加一些方法来尝试确保他们在结帐时使用电子邮件进行注册。为此,我刚刚添加了一项功能,可以在结账时将他们的电子邮件保存在 localStorage 中,并在组合的登录/注册页面上自动填充。但显然,只有当他们使用相同的设备时,这才会有帮助。 我的另一个想法是,我会在每封电子邮件中包含一个令牌,作为我们门户的传出链接的参数,这也会在登录/注册其他设备时自动填充他们的电子邮件。

我的主要问题是上面的斜体句子是否是不好的安全实践。我确实使用NextJS(以及React),所以其中一些是在服务器端呈现的,但我想我必须处理该查询参数在客户端(?),在这种情况下,我可能必须创建一个未经身份验证的端点来将令牌转换为电子邮件。因此,任何拦截 URL 的人(有足够的动机)也可以找出我客户的电子邮件。这是一个合理的风险吗?我是否有不必要的偏执?如果没有,有什么替代方法可以实现我所描述的预期结果?我对想法持开放态度。

还欢迎对上述在 localStorage 中保存纯文本客户电子邮件的做法提出评论。

其他上下文:我使用 Firebase 进行身份验证,所有内容都是用 Typescript 编写的。

javascript reactjs security next.js firebase-authentication
1个回答
0
投票

首先,如果有任何事情触及客户,请将其视为受到损害,直到证明并非如此。您永远不能依赖客户端代码。如果这样做,您必须重新验证服务器端。

让我们从链接中的纯文本电子邮件开始。基本上有两个风险:

  1. 电子邮件泄露,您的客户收到垃圾邮件
  2. 用户可以更改您发送的链接中的电子邮件与其他电子邮件

但风险是影响和可能性的一个因素。在互联网规模上,即使对于低价值资产,您也可以将可能性视为“几乎确定”。

这些事件发生的影响将指导您采取控制措施来防止其发生。如果这只是显示问题,您可能不需要执行任何操作。说“欢迎(错误的电子邮件)”可能不值得修复。

但是如果您依赖此值进行某种形式的身份验证,那么您必须确保:

  • 无法伪造
  • 不能与其他值交换
  • 不能永久重复使用

您可能还需要考虑这些要求:

  • 客户隐私有保障
  • 它可以扩展

这可能是一个完整的项目,但用“令牌”替换电子邮件就可以了:

  • 生成一个像
    generated_timestamp+email
    这样的字符串,也许还有一些上下文,比如账号之类的。例如
    [email protected]_123456
    。以分钟或小时为单位的时间戳就足够了。
  • 对其进行加密(这是一个棘手的部分,稍后会详细介绍)
  • Base64结果就是你发送的token

当服务器(记住,客户端不可信)收到令牌时,它将:

  1. 解密令牌。如果解密失败,拒绝(见下面的注释)
  2. 解析它。如果您无法获取时间戳+电子邮件(和上下文),请拒绝
  3. 如果时间戳早于N天,则拒绝。 30 到 120 天似乎是合理的,但请使其可配置
  4. 如果你到达这里,令牌就可以被认为是有效的

有关密钥管理的一些注意事项:

  • 支持密钥轮换。使用
    current
    密钥解密,如果失败,请尝试使用
    previous
    密钥(如果有)。如果再次失败,请拒绝
  • 我建议使用 128 位密钥的 AES-SIV 或 AES-GCM-SIV 算法和模式。如果可以避免争论和开会,请使用 256 位。
  • 每个主机都需要访问相同的密钥(每个版本)
  • 您需要确保新密钥可用才能使用,因此具有
    current
    future
    previous
    密钥的方案将简化部署
  • 尝试使用算法的
    future
    密钥进行解密,并将其用作现在是
    current
    密钥的信号
  • 在 N 天后(或在
    previous
    密钥变成
    future
    后)删除
    current
    密钥,因为无论如何你都会拒绝这些令牌。
© www.soinside.com 2019 - 2024. All rights reserved.