有很多方式可以在像 SparkPost 这样的 API 优先产品中构建身份验证,我们早期选择的方法是使用 API 密钥。将您的 API 密钥作为原始 Authorization 头注入或通过标准 HTTP Basic Auth 传递,使得使用我们的 API 非常简单。这种 API 密钥在 Web 服务中是一个常见标准,但这个系统有多安全呢?
风险
使用任何 Web 服务时,如果攻击者获得了您的 API 密钥,他们可以代表您进行操作,以及做诸如(在我们案例中)以下事情:
通过您的账户免费发送他们的电子邮件
下载您的收件人名单并将其提供给垃圾邮件发送者(如果他们自己不是垃圾邮件发送者)
编辑您的模板以注入网络钓鱼链接
代表您发送垃圾邮件或网络钓鱼信息
这些结果可能对您的声誉和业务造成严重损害,在网络钓鱼的情况下,甚至可能直接损害您的终端用户。这就是为什么确保没有人能发现您的 API 密钥是极其重要的。
几率
我听到 暴力破解 吗?我们的 API 密钥是随机生成的 40 位长的十六进制字符串。这使得总共有 1.4615e+48 个 API 密钥。如果全世界的 30 亿台计算机和智能手机每秒尝试 100 个 API 密钥,假设我们的服务器允许这样做,通过所有可能的 API 密钥将需要超过 150,000,000,000,000,000,000,000,000,000 年。那么暴力破解 API 密钥显然是不合理的。
那么,如何有人能找到您的 API 密钥?因为密钥作为头传递,可以通过中间人攻击读取,因此您应该始终确保您的客户端在连接到我们的 API 时验证 SSL 证书(这是我们要求 API 连接使用 https 的主要原因)。此外,如果您在使用公开代码库(如 GitHub)时不小心,您的 API 密钥很容易在网上暴露。这不是一个学术问题:有已知的机器人正在爬取 GitHub 以寻找 API 密钥,并且已经通过这个途径发生了 成功攻击。
IP 白名单保护
当您创建一个 API 密钥时,您可以指定一个授权使用该密钥的 IP 列表。您可以指定多个 IP,以及使用 CIDR 表示法 的 IP 块,因此您不必单独列出您的服务器。当使用 API 密钥时,对于 REST API 或 SMTP,我们会将连接的 IP 与此列表匹配,以允许或拒绝访问。
通过这项功能,即使您的 API 密钥被发现或窃取,只有您的服务器才能使用它。考虑到风险及其设置的简便性,我们强烈建议所有客户使用此功能。
最后的建议
关于安全性的一些个人建议:
不要把您的 API 密钥保存在代码中。将其作为环境变量保存有很多好处,就像 Heroku 所做的那样
您可以创建无限数量的 API 密钥,出于安全考虑,最好将责任分散在多个 API 密钥之间,而不是仅仅使用一个万能密钥。这也会让您为每个密钥有不同的 IP 白名单,从而进一步分离关注点
如果您与第三方合作,请不要分享您的 API 密钥,而是为他们创建一个新密钥,只有必要的权限,并附加到他们的 IP
由于 API 密钥只能通过 UI 创建,在您的 SparkPost 账户中启用 2 因素认证 是必须的,并且仅需 2 分钟