如何限制 JSON 访问?
Posted
技术标签:
【中文标题】如何限制 JSON 访问?【英文标题】:How do I restrict JSON access? 【发布时间】:2010-10-25 18:10:37 【问题描述】:我有一个从我新创建的 JSON API 中提取数据的 Web 应用程序。
我的静态 html 页面通过 javascript 从静态 HTML 页面动态调用 JSON API。
如何限制对我的 JSON API 的访问,以便只有我(我的网站)可以从中调用?
如果有帮助,我的 API 类似于:http://example.com/json/?var1=x&var2=y&var3=z... 它会根据查询生成适当的 JSON。
我正在使用 php 来生成我的 JSON 结果...限制对 JSON API 的访问是否可以像检查 $_SERVER['HTTP_REFERER']
以确保 API 仅从我的域而不是远程用户调用一样简单?
【问题讨论】:
只是为了澄清,你是想让它只有你的服务器可以使用 API,还是只有从你的服务器查看网站的人? 我的 JSON api 位于:example.com/json?... 我只希望我的网站 example.com 能够从我的 JSON api 中检索结果。 只是出于好奇,您为什么要这样做?这有点违背网络的规律,所以很高兴知道这个要求背后的原因。 因此,您将发出多个服务器请求,并使用解释的 javascript 将页面拼凑在一起,而不是浏览器向服务器发出单个请求并将页面构建在高端服务器上使用微不足道的客户端。我希望结果对你来说更快。附言这只是半开玩笑 @Darrel:这真的取决于规模和功能。在规模上,我们中的一些人必须处理由 CDN 提供的静态 HTML、JSON 被适当缓存、陈旧时、由无状态、非粘性集群提供服务等等。在这些规模上,每个客户端一台微不足道的上网本或智能手机的性能使每个并行会话可用的服务器内核的 0.1-0.01% 相形见绌。 【参考方案1】:如果您使用 API 的静态页面需要在公共 Internet 上,那么这里的任何解决方案都将是不完美的。由于您需要能够让客户端的浏览器发送请求并获得响应,因此几乎任何人都可能确切地看到您是如何形成该 URL 的。
您可以让 API 背后的应用检查 http 引荐来源网址,但如果有人愿意,这很容易伪造。
如果不要求页面是静态的,您可以尝试使用 API 生成的短期“密钥”并包含在作为参数传递的第一页的 HTML 响应中回到 API。这会增加 API 的开销,因为您必须让该端的服务器维护有效的“密钥”列表、它们的有效期等。
因此,如果有人真的愿意,您可以采取一些不会花费很多但不难解决的步骤,或者您可以花更多时间让它变得更难一点,但没有完美的如果您的 API 必须是可公开访问的,则可以这样做。
【讨论】:
这可能是最优雅的解决方法,但我同意这只是一种解决方法,而不是真正的解决方案(没有)。 所以你的意思是......如果我检查了“HTTP_REFERER” - 至少提供了一些有限的保证,只有我的网站正在使用我的 JSON api。但话又说回来,“HTTP_REFERER”很容易被伪造。【参考方案2】:简短的回答是:任何可以访问您网站页面的人也可以访问您的 API。
您可以尝试通过以各种方式加密 API 来增加使用 API 的难度,但由于您必须包含用于解密 API 输出的 JavaScript 代码,因此您只是在为自己的 API 做准备与任何决定通过其他方式使用您的 API 的人进行军备竞赛。即使您使用短期密钥,一个坚定的“攻击者”也总是会在使用 API 之前抓取您的 HTML(连同当前密钥)。
如果您只想阻止其他网站在其网页上使用您的 API,那么您可以使用 Referrer 标头,但请记住,并非所有浏览器都会发送 Referrer(有些代理也会删除它们!)。这意味着您希望允许所有缺少引用者的请求,而这只会给您部分保护。此外,Referrer 很容易被伪造,因此如果其他网站真的想要使用您的 API,他们总是可以欺骗浏览器并从他们的服务器访问您的 API。
【讨论】:
我不想加密它,我只是想限制“谁”可以调用我的 JSON api。我希望能够调用 API 的唯一人是我自己的 Web 服务器,并且没有远程用户。 是的,这就是我回答的最后一段的内容。您可以尝试使用引荐来源网址,但它很容易被欺骗。【参考方案3】:限制对您的域的访问的常用方法是在内容前面添加无限运行的内容。
例如:
while(1);"json": "here" // google uses this method
for (;;);"json": "here" // facebook uses this method
因此,当您通过 XMLHttpRequest 或任何其他仅限于您的域的方法获取此信息时,您知道您需要解析出无限循环。但是如果是通过脚本节点获取的:
<script src="http://some.server/secret_api?..."></script>
它会失败,因为脚本永远不会超出第一条语句。
【讨论】:
说什么?您的建议是创建一个无限循环?要么我完全错过了这里的东西,要么你在拉我的腿。 除非任何人仍然可以从服务器端代码调用它而无需任何麻烦,只需去掉循环。 是的,JameZ,这是正确的。 JSON 前面的无限循环将阻止您的 JSON 加载到脚本节点中。是的,它不会阻止服务器到服务器的访问。这不是万能的解决方案。这只是另一层安全。它将阻止您的数据使用脚本节点在客户端加载。 Amarghosh:您的解释适用于同一个域。但是,xhr 受域限制。回答你的问题:不,你不能。 有些还会在 json 之前返回不可解析的代码,例如,angularjs 期望在 json 响应的开头有一个)]',\n
。【参考方案4】:
我认为您可能误解了 从用户的浏览器而不是从您自己的服务器发起 JSON 请求的部分。静态 HTML 页面被传递到用户的浏览器,然后它转身并执行页面上的 Javascript 代码。此代码打开一个新连接返回到您的服务器以获取 JSON 数据。从您的 PHP 脚本的角度来看,JSON 请求来自外部世界的某个地方。
鉴于上述机制,您无法阻止任何人在您的 HTML 页面上下文之外调用 JSON API。
【讨论】:
如果是这样的话,人们如何投射他们的“RESTful” api?还是这些 API 都是公开的? 一般来说,它们是公共 API。根据网站的不同,它们可能会或可能不会被记录以供公众使用,但在构建它们时都应该着眼于面对恶意(或只是不受欢迎的)用户时的稳健性。 那么人们如何阻止用户提交一个简单地从 Web 应用程序数据库中转储所有数据的 REST 查询。 API 的设计方式使调用用户无法执行您不想执行的操作。例如,糟糕的 JSON API 会接受 SQL “where”子句并将其直接传递给数据库。即使它已经过净化并且免受注入攻击,您可能不希望您的用户能够查询任何范围的记录。更好的 API 可能会接受记录 ID 或关键字或其他内容,并最多返回 10 条记录。关键是,你不能相信来自外部世界的任何东西。【参考方案5】:在我看来,你不能限制访问,只能让它变得更难。这有点像默默无闻的访问限制。推荐人很容易被伪造,即使使用短暂的密钥,脚本也可以通过不断刷新密钥来获得响应。
那么,我们可以做什么?
找出这里的弱点:
http://www.example.com/json/getUserInfo.php?id=443
攻击者现在可以轻松地循环请求从 1 到 1.000.000 的所有用户信息。 auto_increment
ID 的弱点在于它们的线性度并且很容易猜到。
解决方案:为您的数据使用非数字唯一标识符。
http://www.example.com/json/getUserInfo.php?userid=XijjP4ow
你不能循环这些。诚然,您仍然可以为各种密钥解析 HTML 页面,但这种类型的攻击是不同的(并且更容易避免的)问题。
缺点:当然,您不能使用此方法来限制不依赖于键的查询,例如搜索。
【讨论】:
【参考方案6】:对不起,也许我错了,但是...可以使用 HTTPS 制作吗?
您可以 (?) 通过 https://example.com/json/?var1=x&var2=y 访问您的 API,因此只有经过身份验证的消费者才能获取您的数据...
【讨论】:
SSL 不保证身份,它只是防止第 3 方在浏览器和服务器之间传输数据时看到您的数据。【参考方案7】:您是,还是可以使用基于 cookie 的身份验证?我的经验是基于 ASP.NET 表单身份验证,但同样的方法在 PHP 上应该是可行的,只需少量代码。
基本思想是,当用户通过 Web 应用进行身份验证时,会将具有加密值的 cookie 返回给客户端浏览器。然后,json api 将使用该 cookie 来验证调用者的身份。
这种方法显然需要使用 cookie,因此这对您来说可能是也可能不是问题。
【讨论】:
【参考方案8】:抱歉,网络上没有 DRM :-)
您不能将 HTML 视为受信任的客户端。这是一个在其他人的计算机上按照他们认为合适的方式解释的纯文本脚本。无论您允许什么“自己的”JavaScript 代码,您都允许任何人。你甚至无法用Greasemonkey 和Firebug 在野外定义它是“你的”多长时间。
您必须在服务器中复制所有访问控制和业务逻辑限制,就好像它们都不存在于您的 JavaScript 客户端中一样。
在您的 SSO 中包含该服务,限制每个用户可以访问的 URL,设计服务时将 wget 作为客户端,而不是您表现良好的 JavaScript 代码。
【讨论】:
哦,当人们开始以您的 HTML 不允许的方式使用您的服务时?接受免费的业务发展建议并继续努力!以上是关于如何限制 JSON 访问?的主要内容,如果未能解决你的问题,请参考以下文章