Firebase云功能:如何处理持续请求
Posted
技术标签:
【中文标题】Firebase云功能:如何处理持续请求【英文标题】:Firebase cloud function: how to deal with continuous request 【发布时间】:2018-04-13 11:57:12 【问题描述】:在使用 Firebase(本例中为 Firebase 云功能)时,我们必须为每个字节的带宽付费。
所以,我想知道我们如何处理以某种方式找到我们的端点然后故意(通过脚本或工具)连续请求的情况?
我在互联网上进行了一些搜索,但没有发现任何帮助。 this one 除外,但不是很有用。
【问题讨论】:
【参考方案1】:由于您没有指定哪种类型的请求,我假设您指的是 firebase 云函数上的 http(s)-triggers。
您可以设置多个限制器来“减少”请求所消耗的带宽。我会写一些我想到的
1) 限制请求类型
如果您只需要 GET
并且例如说您不需要 PUT
,则可以先为这些返回 403,然后再继续使用云功能。
if (req.method === 'PUT') res.status(403).send('Forbidden!');
2) 如果可以,进行身份验证
Follow Google's example here 并只允许授权用户使用您的 https 端点。您可以通过验证令牌 like this SOF answer 到 this question 来简单地实现这一点。
3) 检查来源
您可以先检查请求的来源,然后再进一步了解您的云功能。如果我没记错的话,云函数让您可以完全访问 HTTP 请求/响应对象,因此您可以设置适当的 CORS 标头并响应飞行前的 OPTIONS 请求。
实验构想1
您可以假设将您的函数放在load balancer / firewall 后面,然后中继触发它们。它或多或少会破坏云功能的可扩展性的目的,但如果某种形式的 DoS 对您来说比可扩展性更重要,那么您可以尝试创建一个应用引擎中继,将其放在负载均衡器/防火墙后面并处理该层的安全性。
实验思路2
您可以尝试使用 DNS 级别的攻击预防解决方案来解决您的问题,方法是在两者之间放置类似 cloudflare 的东西。使用 CNAME 和 Cloudflare Page Rules 将 URL 映射到您的云函数。假设这可以吸收影响。像这样:
*function1.mydomain.com/*
-> https://us-central1-etc-etc-etc.cloudfunctions.net/function1/$2
现在如果你去
http://function1.mydomain.com/?something=awesome
您甚至可以将 URL 参数传递给您的函数。我在夏天需要类似的东西时读到了关于in this medium article 的策略。
终于
为了让 SOF 上的问题更紧密地联系起来,并帮助大家找到答案,here's 我发现另一个性质相似的问题。在这里链接,以便其他人也可以找到它。
【讨论】:
感谢您的回答。除了 Cloudfare,我都做了,谢谢。所以,最后我们需要小心计算每次再见的成本,现在请求保护自己。 @LạngHoàng 很高兴它有帮助! :) 我仍然会做数学,看看它会导致什么。可能仍然值得查看 Cloudflare 的定价并进行比较。在非常特殊的情况下,cloudflare 最终可能会更便宜。 @johnozbay : 对于 1) 限制请求类型,我认为 Google 甚至在 @987654334 之前就已经开始向我们收取调用费用了@响应码发送?我的意思是向403
发送 100,000 次垃圾邮件仍然是一笔不小的费用,对吧?
@AntonioOoi 您可能希望使用这些解决方案的组合来有效地领先于垃圾邮件和攻击。重要的是要弄清楚你的威胁/防御模型是什么,并围绕它构建你的解决方案。如果这不是云功能,人们仍然可以向您的端点发送垃圾邮件和 DDOS。你会在服务器前面放一些东西来保护它,然后为此付费。如果您担心大规模垃圾邮件/DDOS,您应该查看 Cloudflare 的产品。【参考方案2】:
这个问题有一个解决方案,您可以验证 https 端点。
只有在 HTTP 请求的 Authorization 标头或 __session cookie 中将有效 Firebase ID 令牌作为 Bearer 令牌传递的用户才有权使用该函数。
使用 ExpressJs 中间件检查 ID 令牌,该中间件也将解码的 ID 令牌传递到 Express 请求对象中。
检查来自 firebase 的 this 示例代码。
【讨论】:
这很容易验证,我知道怎么做,但很多情况下我们需要提供一个公共端点,然后任何人都可以使用。关键是如何对付想要攻击我们的人。【参考方案3】:在不受支持的方法上返回 403 或空正文对您没有多大帮助。是的,您将浪费更少的带宽,但 firebase 仍会为请求向您收费,攻击者可能只发送数百万个请求,您仍然会赔钱。
身份验证也不是解决此问题的方法。首先,任何身份验证过程(创建令牌、验证/验证令牌)都是昂贵的,firebase 再次考虑到这一点,并将根据函数返回响应所需的时间向您收费。您不能使用身份验证来阻止连续请求。
另外,一个聪明的攻击者不会只去请求返回 403 的请求。是什么阻止了攻击者点击登录端点数百万次?如果他提供正确的凭据(如果他很聪明,他会这样做),您将通过每次返回令牌来浪费带宽,而且如果您重新生成令牌,您将在每个请求上浪费时间,这会进一步损害您的账单。
这里的想法是完全阻止这个攻击者(在使用你的 api 函数之前)。 我要做的是使用 cloudflare 代理我的端点,并在我的 api 中定义一个 max_req_limit_per_ip 和一个 time_frame,将每个请求 ip 保存在 db 上,并在每个 req 检查 ip 是否超过给定时间范围的限制,如果是这样,您只需使用 cloudflare api 在防火墙处阻止该 ip。
提示: max_req_limit_per_ip 和 time_frame 可以为不同的请求定制。
例如:
-
一个 ip 可以在 1 小时内达到 403 10 次
一个ip可以在20分钟内成功登录5次
一个ip可以在1小时内5次登陆失败
【讨论】:
“我要做的是使用 cloudflare 代理我的端点”你怎么能做到这一点...... 不错!如何设置这些限制?【参考方案4】:在您的函数中加入访问控制逻辑是 Firebase 的标准做法,但仍必须调用该函数才能访问该逻辑。
如果除了经过身份验证的用户之外,您完全不希望您的函数触发,您可以利用每个 Firebase 项目也是 Google Cloud 项目这一事实 - 并且 GCP 允许“私有”功能。
您可以在函数外部设置项目范围或每个函数的权限,这样只有经过身份验证的用户才能触发函数,即使他们尝试访问端点。
这是关于 setting permissions 和 authenticating users 的文档。请注意,在撰写本文时,我相信使用此方法需要用户使用 Google 帐户进行身份验证。
【讨论】:
以上是关于Firebase云功能:如何处理持续请求的主要内容,如果未能解决你的问题,请参考以下文章
firebase、flutter应该如何处理好友请求和邀请? [关闭]
如何处理 firebase 动态链接的生命周期? (iOS)