Hi Mongo
(recreated topic as more info and could not edit original)
I have been experimenting with Realm 3rd Party Services to create incoming webhooks, Based on the scalability I am particularly interested in preventing attacks on the endpoint and how to prevent an attacker requesting the endpoint over and over and causing a “denial of wallet” attack.
I expected that using the ‘Can Evaluate’ expression combined with a list of abusive IP’s would mitigage basic attacks by blocking the request from being procesed; however from testing this does not seem to be the case - I can prevent the funtion from running so reducing Data Transfer and Compute Runtime but I cannot prevent the request from being billed.
Can you answer the following:
-
Is there any way for me to completely deny a request to an endpoint and not be charged for the request?
-
Does Mongo have any recomended practices for mitigating endpoint attacks (for example you provide a json expression showing allow if in set of ip but this is useless if the request is still charged)?
-
What protection does Mongo provide at the Realm platform level to mitigate platform level / large scale ddos attacks on endpoints and how does this impact our billing if our endpoints are targeted?
-
What protection does Mongo provide at the Realm platform level to mitigate targetted ddos attacks
on our endpoints and how does this impact our billing?
For example Firebase provide a platform level ddos protection that prevents billing of clients if there was a platform level ddos attack; however this is retrospective and would only apply in case 3, they provide support for case 2 but very little for case 1 which can result in unessecary billing for clients.
Thank you,
I have included case studies and test setup below.
Case studies:
Case 1: A basic attacker requesting an endpoint over and over again using a basic load testing tool running 50req/s which would be processed by Realm and result in an additional 4.3M requests per day:
( ( 50 req/s * 86400 s/day ) / 1000000 ) * 0.3 = $1.29 / day
In this case I could identify the attacker and prevent the function being run for them but I cannot completely deny the requests; this would result in a $40/month cost when normal load might only run < 5$
Case 2: A basic distributed attack could request an endpoint over and over again lets say a cluster of 100 bots requesting the endpoint at 50 req/s which would be processed by Realm and result in ~430M requests per day:
( ( 100 bots * 50 req/s * 86400 s/day ) / 1000000 ) * 0.3 = $129+/day
Here again the IPs could be identified but not completely denied and we would have to terminate the app to prevent a bill of $4000+ for the month.
Case 3: A sophisticated attacker could distribute the attack using multiple rotating bots and target all of the apps endpoints - assuming the app has 10 endpoints and using a sustained 200 bot attack:
( ( 10 endpoints * 200 bots * 50 req/s * 86400 s/day ) / 1000000 ) * 0.3 = $2592 /day
Test setup:
My testing setup using the UI for setup and leaving all defaults unless specified:
- Create an Atlas cluster
=> AWS, Frankfurt (eu-central-1), 4.4, M0, Name = cluster - Create a Realm app connected to the cluster
=> Name = app, link to cluster, set global - Create a 3rd Party Service
=> 3rd Party Services => Add a Service => Type = http, Name = test - Add an incoming webhook to the service
=> Add Incoming Webhook => Name = test, HTTP Method = GET
Test 1 - Setup endpoint to return ‘Hello World’, expect request to be processed and request billed.
Outcome: Endpoint returns and 1 request is billed
% curl https://webhooks.mongodb-realm.com/api/client/v2.0/app/APP/service/test/incoming_webhook/test
"Hello World!"
Test 2 - Set Can Evaluate to always false expect request to be denied
=> Edit Webhook => Can Evaluate = { “%%true”: false }
Outcome: Endpoint returns error but 1 request is still billed
% curl https://webhooks.mongodb-realm.com/api/client/v2.0/app/APP/service/test/incoming_webhook/test
{"error":"incoming webhook evaluation blocked by CanEvaluate","link" ... }