77

目前,Google 要求您创建一个特定于将提供地图的域的 API 密钥。Google 如何执行此操作?我想做同样的事情。

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

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

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

4

5 回答 5

66

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

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

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

当然,还有可能通过他们的 API 进行 XSS 攻击的担忧。但我不相信他们的 API 密钥与他们拥有的任何反 XSS 代码有太多关联。

于 2010-02-13T04:34:59.500 回答
30

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

举个实际的例子,使用 PHP 你可以检查域名$_SERVER['HTTP_REFERER']来检查引用者。如果域匹配,则返回有效响应。如果没有,您可以返回 401 Unauthorized 或其他响应。

于 2010-02-13T02:59:25.890 回答
4

正如我的评论所说:

REFERER 具有欺骗性,因此 Google 不太可能将其用作验证手段。请参阅此维基百科条目。

我的猜测是,谷歌可能会使用调用者的 IP 地址以及 DNS 查找。DNS 并不是真正的欺骗性,因为您的 DNS 条目必须正确,网站才能找到您。

但是,即使这样也有问题,因为如果服务器使用循环 IP 地址 DNS 设置,Google 在进行 DNS 查找时将被重定向到不同的 IP 地址。

来自常见问题

请注意,只有在使用此地址访问该站点时,才会接受http://www.mygooglemapssite.com/的密钥。如果该站点是通过 IP 地址(例如http://10.1.2.3/)或使用 DNS CNAME 记录别名为 www.mygooglemapssite.com 的主机名访问的,则不会被接受。

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

我的猜测得到了支持,因为它不适用于 IP 地址或别名,这意味着它没有进行 DNS 检查。

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

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

于 2010-02-13T03:16:24.653 回答
3

我同意弗朗西·佩诺夫列出的所有观点。我想详细说明一下使用别人的 API 密钥。让我们假设您key1example.com.

  1. 第一次尝试 - 如果anothersite.comhas <script src="http://www.google.com/jsapi?key=key1">,Google 可以检查其引荐来源网址(提到的哈希方案),在这种情况下存在不匹配。既然很多人都提到可以欺骗引用者,那么邪恶的攻击者如何克服这一点?这在这里并不真正适用。当然,如果您提出请求,您可以发送任意标头,但是邪恶的黑客如何欺骗用户的引荐来源网址anothersite.com?这通常并不容易。IE 6 上有旧版本的 flash 允许攻击者在发出跨域请求时设置任意标头,但通常这对于 script 是不可行的src。我不确定包含的 Javascript 是否会进行任何验证document.location以防止这种情况发生(可能不会)。

  2. 第二次尝试 - 一个邪恶的攻击者从 的页面源中复制用于 API 密钥的 Google Javascript,mysite.com然后将修改后的 javascript 嵌入到anothersite.com. 现在 Google 无法检查任何内容(远程 IP 将是用户的计算机,您或 Google 无能为力)。

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

于 2010-02-16T19:30:59.013 回答
-6

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

于 2010-02-13T03:01:11.190 回答