如何防止任意客户端应用程序使用匿名 Web API?

Posted

技术标签:

【中文标题】如何防止任意客户端应用程序使用匿名 Web API?【英文标题】:How to prevent arbitrary client apps from using anonymous web API? 【发布时间】:2011-07-17 01:03:05 【问题描述】:

抱歉,如果这个问题已经被询问和回答;我环顾了一堆,但没有找到我要问的确切内容。

--

    假设我在 http://example.com/ 的 Web 应用程序使用 http://api.example.com/ 的私有且未记录的 Web API 来获取数据,例如通过 XHR 或 JSONP。

    另外假设这个网络应用是匿名的——它确实不需要需要用户登录。

    由于客户端和服务器之间有通信,任何人都可以打开Fiddler等查看确切的请求和响应,更不用说检查客户端JS代码了。

在这种情况下,您如何防止有人在非网络客户端应用程序中使用您的 API?例如。 iPhone 应用程序或服务器端。

据我了解,第 2 点删除了 OAuth 之类的选项,第 3 点删除了例如API 密钥甚至 SSL。

我考虑过诸如基于时间的令牌或在首次加载时注入页面的秘密盐之类的东西,但 iPhone 应用程序可以轻松地在发出 API 请求之前秘密地加载您的网页。

那么除了简单的混淆之外还有什么办法——通过默默无闻来保证安全?

--

如果这一切都太抽象了,这里有一个简单的例子:

Google.com 通过一些私有且未记录的 API 获取其自动完成数据 - 但在网络上开放。是什么阻止我在 iPhone 应用中使用它?

【问题讨论】:

Google 的条款和条件以及他们比您拥有更多资金和律师的事实? :P 他们怎么会知道呢?我真的在问;欺骗User-Agent和Referer是微不足道的,每个用户都有不同的IP地址等。 @Aseem 他们可能不一定知道,但他们可能每分钟处理数百万个合法请求,有几个外部请求? 什么意思,他们怎么会知道?他们不是什么都知道吗?我的意思是,我们在这里谈论的是 Google。 @Alex 所以你的意思是,这对谷歌来说不是问题。如果你没有谷歌那么大怎么办? 【参考方案1】:

身份验证也不能防止滥用您的 API。只要客户端可以正确地通过您的系统进行身份验证,他就可以使用他/她选择的任何客户端。只有在客户端和服务器都安全且连接安全的情况下,才能避免滥用。

如果问题是滥用,那么简单的限制解决方案可能就足够了。

【讨论】:

【参考方案2】:

您无法阻止人们复制您的客户端代码或重放网络流量。

感谢same origin policy,其他网络应用程序无法从客户端访问您的 API。他们必须通过服务器代理他们的请求,这意味着这些请求将来自少数易于识别的 IP 地址,您可以将其暂时列入黑名单。

对于桌面应用和移动应用,您无能为力。我的建议是在它们成为问题之前不要担心它们。

也就是说,做好准备并没有什么坏处。如果您想避免昂贵的法律纠纷,您可以做的一件事是不时更改您的 API 方法签名。浸出应用程序可以修复,但它们的声誉会稳步下降。

【讨论】:

谢谢。你是对的,在它真正成为一个问题之前,这不值得过度担心,并且更改方法签名的建议是一个很好的反应措施。 感谢理查德·普尔。【参考方案3】:

如果您的客户端有对窥探者隐藏的代码,您能否不按照您的建议使用盐、IP 地址和基于时间的值,对它们进行加密,然后在服务器端执行相同操作?这基本上就是 mod_auth_tkt 所做的,而且效果很好。或者这会构成身份验证吗?

【讨论】:

虽然您发送到浏览器的最终是代码或秘密,是吗?无论哪种情况,我现在都可以看到它并在我未经授权的客户端应用程序中使用它。我确实知道这会增加一些晦涩的层次,这会有所帮助;我只是想知道是否有一种“真正的”安全方式。 是的,nyamaybe ...在您设置的时间窗口内完成。任何不知道您的有效 IP 的人也必须知道您的秘密。这当然可以做到,但我想在大学校园(和星巴克)之外几乎没有滥用。 - 显然这不安全 - 因为我永远不会在此基础上做任何涉及大量价值的事情,但这可能足以阻止潜在的黑客。 顺便提一下,Azure 公共存储 blob 的 SAS“安全”机制仅使用时间戳(和机密)——而且许多 mod_auth_tkt 实现也不使用 IP 地址... 如果任何人都可以使用您的 Web 应用程序,您如何将令牌基于 IP 地址?我猜这就是 Azure blob 存储仅使用时间戳的原因。继续这个例子,如果你想在 在网页上 以这种方式保护的 blob 存储中显示图像,你怎么可能阻止 iPhone 应用程序显示相同的图像?我可以在隐藏的 UIWebView 中加载您的网页,获取 html 中的图像 URL,然后在我的应用程序中使用它。 换一种说法:如何通过假装它是一个网络浏览器(欺骗 WebKit 用户代理)从你的网页发出请求(欺骗引用者)来防止任何 iPhone 应用程序使用你的 API一些随机用户的计算机(所以不能使用 IP 地址)?【参考方案4】:

如果没有 API 密钥或某种形式的授权,您将在试图阻止未经授权的客户为您服务的过程中打一场失败的战斗。

你可以嗅出很多东西,但最容易伪造的是硬道理。

您控制其他网络服务吗?此外,如果您的 Web 应用程序 (http://example.com/) 通过 XHR 或 JSONP 访问 API (http://api.example.com/),您是否可以通过使用诸如 cURL 之类的库来代理服务器上的数据来获取数据,然后使其可用您的网站。然后,您可以以任何您认为合适的方式控制对它的访问。

【讨论】:

对不起,我不关注。如果您从客户端向服务器发出请求,您将如何获得 API 密钥? (即任何人都可以打开 Fiddler 并嗅探您的 API 密钥。)我也不明白通过您自己的服务器进行代理会有什么帮助。将示例 API 端点更改为 example.com/api,情况保持不变。 如果你通过你的服务器代理,你可以使用身份验证或任何你想传回信息的方法。 我很抱歉,但你能做什么样的身份验证?该应用程序是匿名的,任何黑客仍然可以使用 Fiddler 来检查请求/响应。 @Aseem 我不认为你是密集的,你在问正确的问题。您可以通过要求随每个请求发送一个随机数来使事情变得更加困难,该随机数由父 HTTP 请求创建(即 XHR 发送它)。虽然我正在对您的服务及其运作方式做出假设。 但是我不能在隐藏的 UIWebView 中加载网页来获取这个随机数吗?

以上是关于如何防止任意客户端应用程序使用匿名 Web API?的主要内容,如果未能解决你的问题,请参考以下文章

MeteorJS - 如何防止匿名客户端订阅集合?

如何限制对Web API 2应用程序中的已知客户端应用程序的API访问?

如何限制对 Web API 2 应用程序中已知客户端应用程序的 API 访问?

如何防止签名令牌用户通过浏览器开发工具访问 API 响应?

使用 imgur api v3 使用 php 匿名上传图片

如何防止从客户端向服务器端发送数据(位置、纬度和经度)作弊?