Google 地图如何保护其 API 密钥?如何制作类似的东西?
目前,Google 要求您创建一个特定于提供地图的域的 API 密钥。谷歌如何强制执行这一点?我想做同样的事情。
我为我的服务公开了一个 API,但希望允许客户端通过 JavaScript 而不仅仅是从服务器嵌入对 API 的调用。我可以仅使用随机令牌来保护它,但当然,任何查看客户端计算机上代码的人都可以轻松欺骗它。
我一直认为这个概念是不可能的,但不知何故,谷歌在执行它方面做得很好。
编辑 - 听起来谷歌毕竟还没有做出任何令人惊奇的事情。他们的 API 很可能只是用于跟踪,而不是真正保证拥有密钥的人使用他们的 API。
Currently Google requires you to create an API Key that is specific to the domain of where the map will be served from. How does Google enforce this? I want to do the same thing.
I expose an API for my service but want to allow clients to embed calls to the API via javascript and not just from the server. I could secure it with just a random token but of course this could be easily spoofed by anyone looking at the code on the client machine.
I always understood this concept to not be possible but somehow Google does a good job at enforcing it.
Edit - It sounds like Google really hasn't done anything amazing after all. Their API is most likely just for tracking and not really to guarantee that their API is used by the person with the key.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
API 密钥本身很可能是与密钥关联的域的单向哈希,并且是只有 Google API 服务器知道的秘密。它可能包含一些其他众所周知的(当然是谷歌)信息。当您从该域发出请求时,API 服务器会获取请求来自的域并进行相同的单向哈希计算并比较两个值。
对于 Ajax 调用,他们很可能使用引用者来获取文档主机的域。虽然引荐来源网址可能会被欺骗,但最终为了使用 API,您需要获取 Google javascript 在文档中执行。此时,该 javascript 可以验证调用 Ajax API 调用的文档确实源自目标服务器。当然,如果您有自己的 DOM 实现或动态修改脚本,这也是可以欺骗的。然而,这种欺骗需要发生在客户端,想要使用 Google API 的网站能够欺骗客户端软件的机会非常小。
请注意,由于 API 本质上是免费的,因此他们也可以提供对其 API 的匿名访问。显然,谷歌的目的不是保护未经授权的访问,而是确保他们可以收集尽可能多的有关该数据使用情况的数据,并能够将该使用情况与他们收集的有关目标域的其他数据相关联。因此,我不希望 API 密钥验证比我上面描述的复杂得多 - 更先进的方法的投资回报率太低。
当然,还有可能通过其 API 进行 XSS 攻击的担忧。但我不认为他们的 API 密钥与他们拥有的任何反 XSS 代码有太多的联系。
The API key itself is most probably a one way hash of the domain the key is associated with and a secret only the Google API server knows about. It may contain some other pieces of well-known (to Google of course) information. When you make a request from that domain, the API server takes the domain the request comes from and makes that same one way hash calculation and compares the two values.
For Ajax calls, they most probably use the referrer to get the domain of the document host. While the referrer can be spoofed, ultimately in order to use the API, you need to get Google javascript to execute in the document. At this point, this javascript can verify that indeed the document that invoked the Ajax API call originated from the target server. This is also spoofable of course, provided you have your own DOM implementation or on the fly modification of the script. However, this spoofing needs to happen on the client side and the chances that the website that wants to use Google API will be able to spoof the client software are quite small.
Note that since the API is essentially free, they could've offered anonymous access to their API as well. Apparently Google's intent is not to protect unauthorized access to it, but to ensure that they can gather as much data as possible about that data usage and be able to associate that usage with other data they've collected about the target domain. As such, I wouldn't expect the API key verification to be much more complex than what I described above - the ROI on more advanced approach is too low.
And of course there's also the concern of possible XSS attacks through their API. But I don't believe their API key is tied too much into any anti-XSS code they have.
我非常确定他们使用 REFERER URL 来确定呼叫来自何处。如果域与分配给密钥的域不匹配,则该请求无效。
作为一个实际示例,使用 PHP,您可以使用
$_SERVER['HTTP_REFERER']
检查域来检查引用站点。如果域匹配,则返回有效响应。如果没有,您可以返回 401 Unauthorized 或其他响应。I'm quite certain they use the REFERER URL to determine where the call is coming from. If the domain doesn't match what's assigned to the key, it's an invalid request.
For a practical example, using PHP you can check the domain using
$_SERVER['HTTP_REFERER']
to check the referer. If the domain matches, return a valid response. If it doesn't, you can return a 401 Unauthorized or other response.我同意 Franci Penov 列出的所有观点。 我想详细说明一下如何使用其他人的 API 密钥。假设您向
example.com
注册了key1
。第一次尝试 – 如果
anothersite.com
有, Google 可以检查其引荐来源网址(提到的哈希方案),在这种情况下存在不匹配。既然很多人都提到引用者可以被欺骗,那么邪恶的攻击者如何克服这个问题呢?这并不真正适用于此。当然,如果您发出请求,您可以发送任意标头,但是邪恶的黑客如何欺骗
anothersite.com
上的用户的引荐来源网址呢?这一般来说并不容易。 IE 6 上的旧版本 Flash 允许攻击者在发出跨域请求时设置任意标头,但通常这对于脚本src
不起作用。我不确定包含的 Javascript 是否会对document.location
进行任何验证以防止出现这种情况(可能不会)。第二次尝试 – 邪恶的攻击者从
mysite.com
的页面源复制 API 密钥的 Google Javascript,然后在anothersite.com
上嵌入修改后的 JavaScript。现在 Google 无法检查任何内容(远程 IP 将是用户的计算机,您或 Google 无法做很多事情)。因此,如果您出于某种原因想要对您的 API 密钥保密(其中一个原因是,恶意者可以将您的密钥列入黑名单/阻止),那么请勿通过您的服务器将密钥嵌入到客户端和代理请求中(您的应用程序代码现在具有钥匙)。
I agree with all the points that Franci Penov has listed. I would like to elaborate a little bit on using someone else's API key. Let us assume you register
key1
withexample.com
.First attempt – If
anothersite.com
has<script src="http://www.google.com/jsapi?key=key1">
, Google could check its referrer (hash scheme mentioned) and in this case there is a mismatch. How does evil attacker overcome this, since a lot of people have mentioned that referrer can be spoofed? This does not really apply here. Sure you could send arbitrary headers if you make the request, but how does evil hacker spoof referrer for users onanothersite.com
? This is in general not easy. There have been old versions of flash on IE 6 that allowed attacker to set arbitrary headers when making cross domain requests, but in general this is not workable for scriptsrc
. I am not sure if the included Javascript does any validation ofdocument.location
to prevent this (probably not).Second attempt – An evil attacker copies Google Javascript for the API key from
mysite.com
's page source and then embeds modified javascript onanothersite.com
. Now Google can't check anything (the remote IP will be the user's computer, and there isn't a whole lot you or Google can do).So, if you want to for some reason keep your API key secret (one reason, malicious person can get your key blacklisted/blocked), then don't embed key in client and proxy requests via your server (your application code now has the key).
正如我的评论所说:
我的猜测是,Google 可能会使用调用者的 IP 地址以及DNS 查找。 DNS 并不是真正可以欺骗的,因为您的 DNS 条目必须正确,网站才能找到您。
但是,即使这样也有其问题,因为如果服务器使用循环 IP 地址 DNS 设置,Google 在进行 DNS 查找时将被重定向到不同的 IP 地址。
来自常见问题解答
我的猜测是,它可能使用请求页面时发送的
Host
标头,这通常会像 Google 要求您将其 API 脚本直接包含到页面中一样工作。然后该脚本可以访问当前页面的标题并可以使用它进行检查。我的猜测得到了事实的支持,即它不适用于 IP 地址或别名,这意味着它不进行 DNS 检查。
此方法不能被欺骗,因为它必须是正确的标头才能访问该页面。但是,这意味着该域的任何别名都将不起作用。
然而,这也意味着您必须提供一个 Javascript 库来访问代码,因为我相信您无法检查此服务器端。
As my comment says:
My guess is that Google probably uses the IP address of the caller along with a DNS lookup. DNS is not really spoofable, as your DNS entries have to be correct for the website to even get to you.
But, even that has its problems, because if a server uses a Round-Robin IP Address DNS setup, Google will be redirected to a different IP address when doing a DNS lookup.
From the FAQ
My guess is that it might be using the
Host
header that is sent when requesting the page, which would work as normally Google asks you to include it's API script directly into the page. Then that script has access to the headers for the current page and can use that to check.My guess is backed up with the fact that it does not work for IP addresses or Aliases, which means it isn't doing a DNS check.
THIS method cannot be spoofed, as it must be the correct header to access the page. However, this means that any aliases to the domain will not work.
However, this also means that you MUST provide a Javascript library to access the code, as you can't check this server side, I believe.
它起作用的原因是你无法使用 javascript 进行 API 调用。浏览器安全性会阻止 javascript 向除 javascript 源自的域之外的任何地方发出请求。因此,来自 javascript 的任何 API 调用都需要通过存储 API 密钥的服务器退回(javascript 永远不会看到 api 密钥)。
The reason it works is that you cannot make API calls with javascript. Browser security prevents javascript from making requests anywhere except to the domain that the javascript originated from. Because of this, any API calls from javascript need to be bounced through your server where the API key is stored (the api key is never seen by javascript).