使用Firebase(在这种情况下使用Firebase云功能)时,我们必须为每个带宽字节付费。
所以,我想知道我们怎么能处理那些以某种方式找到我们的端点然后有意识地(通过脚本或工具)连续请求的情况?
我在互联网上进行了一些搜索,但没有看到任何可以提供帮助的内容。 除了https://jira.spring.io/browse/DATAREST-713但不是很有用。
答案 0 :(得分:8)
由于您没有指定哪种类型的请求,我将假设您在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
您可以通过在其间放置类似cloudflare的内容,尝试使用针对您的问题的DNS级别攻击防范解决方案。使用CNAME和Cloudflare Page Rules将网址映射到您的云功能。这可能会假设吸收这种影响。像这样:
*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我发现另一个问题本质上是相似的。链接在这里,以便其他人也可以找到它。
答案 1 :(得分:2)
使用不受支持的方法返回403或空白正文对您没有多大帮助。是的,您将浪费更少的带宽,但是firebase仍会为您收取该请求的费用,攻击者可能只发送数百万个请求,您仍然会蒙受损失。
身份验证也不是解决此问题的方法。首先,所有身份验证过程(创建令牌,验证/验证令牌)的成本都很高,firebase再次想到了这一点,并将根据该函数返回响应所花费的时间向您收费。您不能使用auth来阻止连续请求。
此外,精明的攻击者不会仅仅要求返回403的请求。是什么阻止了攻击者数百万次击中登录端点?而且,如果他提供正确的凭据(如果他很聪明的话,他会这样做),那么您将每次通过返回令牌来浪费带宽,而且如果您重新生成令牌,您将在每个请求上浪费时间,这将进一步损害您的账单。 / p>
这里的想法是完全阻止此攻击者(在使用api函数之前)。 我要做的是使用cloudflare代理端点,并在我的api中定义一个max_req_limit_per_ip和time_frame,将每个请求ip保存在db上,并在每个req上检查该ip是否超过了给定时间范围的限制,如果是这样,您只需使用cloudflare api在防火墙处阻止该IP。
提示: 可以为不同的请求自定义max_req_limit_per_ip和time_frame。
例如:
答案 2 :(得分:1)
此问题有一个解决方案,您可以在其中验证https端点。
只有在HTTP请求的Authorization标头或__session cookie中传递有效Firebase ID令牌作为Bearer令牌的用户才有权使用该功能。
使用ExpressJs中间件检查ID令牌,该中间件也传递Express请求对象中的解码ID令牌。
从firebase检查this示例代码。
答案 3 :(得分:1)
在您的函数中放置访问控制逻辑是Firebase的标准做法,但是仍然必须调用该函数才能访问该逻辑。
如果您不希望除已认证的用户外全部触发功能,则可以利用以下事实:每个Firebase项目也是Google Cloud Project,并且 GCP允许“私人”功能。
您可以在功能的外部中设置项目范围或每个功能的权限,这样,即使经过身份验证的用户尝试击中端点,也可以触发该功能。
这里是setting permissions和authenticating users的文档。请注意,在撰写本文时,我相信使用此方法要求用户使用Google帐户进行身份验证。