谷歌地图如何保护他们的 API 密钥? 如何制作类似的东西?

目前,Google 要求您创建一个 API Key,该 API Key 特定于地图将从何处提供服务的域。谷歌如何执行这一点?我也想这么做。

我为我的服务公开了一个 API,但是希望允许客户端通过 javascript 嵌入对 API 的调用,而不仅仅是来自服务器的调用。我可以只使用一个随机令牌来保护它,但是当然,任何查看客户端机器上的代码的人都可以很容易地欺骗它。

我一直明白这个概念是不可能的,但不知为何谷歌在执行这个概念方面做得很好。

编辑-听起来谷歌真的没有做任何惊人的事情毕竟。它们的 API 很可能只是用于跟踪,并不能真正保证拥有密钥的人使用它们的 API。

36231 次浏览

我很确定他们使用 REFERER URL 来确定呼叫来自哪里。如果域与分配给密钥的内容不匹配,则该请求无效。

对于一个实际的例子,使用 PHP,您可以使用 $_SERVER['HTTP_REFERER']检查域来检查引用程序。如果域匹配,则返回有效响应。如果没有,您可以返回一个401未授权或其他响应。

它工作的原因是您不能使用 javascript 进行 API 调用。浏览器安全性防止 javascript 在任何地方发出请求,除了发出 javascript 的域。因此,任何来自 javascript 的 API 调用都需要通过存储 API 密钥的服务器进行反弹(javascript 从来不会看到 API 密钥)。

正如我的评论所说:

REFERER 是可欺骗的,所以 Google 很可能不会将其用作验证手段。参见 这个维基百科词条。

我的猜测是,Google 可能使用调用者的 IP 地址以及 DNS 查找。DNS 不是真正的欺骗,因为你的 DNS 条目必须是正确的网站,甚至到达你。

但是,即使这有它的问题,因为如果一个服务器使用轮循 IP 地址 DNS 设置,谷歌将被重定向到一个不同的 IP 地址时,做 DNS 查找。

常见问题解答

请注意,只有当使用此地址访问站点时,才会接受 http://www.mygooglemapssite.com/的密钥。如以 IP 地址(例如:。或使用 DNS CNAME 记录别名为 www.mygooglemapssite.com 的主机名。

我的猜测是,它可能使用了在请求页面时发送的 Host头文件,正常情况下,Google 会要求您将其 API 脚本直接包含到页面中。然后,该脚本可以访问当前页的标题,并可以使用该标题进行检查。

我的猜测是备份的事实,它不工作的 IP 地址或别名,这意味着它没有进行 DNS 检查。

无法欺骗此方法,因为它必须是访问该页的正确标头。但是,这意味着该域的任何别名都不会起作用。

但是,这也意味着您必须提供一个 Javascript 库来访问代码,因为您不能检查这个服务器端,我相信。

API 密钥本身很可能是与该密钥相关联的域的单向散列,并且是只有 Google API 服务器知道的秘密。它可能包含其他一些众所周知的信息(当然是 Google)。当您从该域发出请求时,API 服务器将获取请求来自的域,并进行相同的单向散列计算,并比较两个值。

对于 Ajax 调用,它们最有可能使用引用程序来获取文档主机的域。虽然可以欺骗引用程序,但是最终为了使用 API,您需要让 Google javascript 在文档中执行。此时,这个 javascript 可以验证调用 Ajax API 调用的文档是否确实来自目标服务器。当然,如果您有自己的 DOM 实现或者对脚本进行动态修改,这也是可以欺骗的。然而,这种欺骗需要发生在客户端,而想要使用 Google API 的网站能够欺骗客户端软件的可能性非常小。

注意,由于 API 本质上是免费的,他们也可以提供对其 API 的匿名访问。显然,谷歌的目的不是保护未经授权的访问,而是确保他们能够收集尽可能多的有关该数据使用的数据,并能够将该数据使用与他们收集的关于目标域名的其他数据联系起来。因此,我认为 API 密钥验证不会比上面描述的复杂得多——更高级的方法的 ROI 太低了。

当然,也有人担心通过 API 可能发生的 XSS 攻击。但是我不认为他们的 API 密钥与他们的任何反 XSS 代码有太多的联系。

我同意 弗朗西 · 佩诺夫列出的。的所有观点,我想详细说明一下使用别人的 API 键。让我们假设您用 example.com注册了 key1

  1. 第一次尝试如果 anothersite.com<script src="http://www.google.com/jsapi?key=key1">,谷歌可以检查它的引用(哈希方案提到) ,在这种情况下有一个不匹配。邪恶的攻击者如何克服这一点,因为很多人已经提到,引用可以欺骗?这并不适用于这里。当然,你可以发送任意的标题,如果你提出请求,但如何恶意黑客欺骗引用的用户在 anothersite.com?这一般来说并不容易。在 IE6上有一些旧版本的 flash,允许攻击者在发出跨域请求时设置任意的头部,但是通常这对于脚本 src是不可行的。我不确定所包含的 Javascript 是否对 document.location进行了验证(可能没有)。

  2. 第二次尝试,一个邪恶的攻击者从 mysite.com的页面源代码中拷贝了用于 API 键的 Google Javascript,然后将修改后的 Javascript 嵌入到 anothersite.com中。现在谷歌不能检查任何东西(远程 IP 将是用户的计算机,你和谷歌都无能为力)。

因此,如果出于某种原因,你想保持你的 API 密钥的秘密性(一个原因,恶意人员可能会让你的密钥被列入黑名单/阻止) ,那么不要通过你的服务器在客户端和代理请求中嵌入密钥(你的应用程序代码现在有了密钥)。