For this attack, an attacker would need to obtain access to your AWS account with at least enough permissions to create a Lambda function with a policy that permits “lambda:InvokeFunction” access.
Once this access is obtained, with about 5 minutes of time they could create a Lambda function that can rack up $176 an hour in your AWS account.
The high-level steps would be:
- Create an IAM Lambda execution role for lambda with lambda:invoke permission
- Create a new lambda function in a language of choice using the above role
- Set memory to 3008 MB (max) and timeout to 15 minutes (max)
- Enter the following pseudocode in the language of choice:
aws = require aws sdk
lambda = aws.lambda
while true
lambda invoke
Function “your function name”
Type Event - Create and run a test to kick off the attack
In theory, this would result in a function being launched which, in turn, launches itself in a never-ending loop. It would not take long to hit the 1000 concurrency limit. Some launched functions will hit the limit and fail but as soon as others timeout, new instances would take their place keeping the total running lambdas at 1000. This means that it will effectively cost you 2.94 per minute for 15 minutes or longer until stopped. If you have an account with higher concurrency limits, then there will be a higher cost risk. This will also behave like a DOS attack, blocking any serverless solutions you have running due to maxing out the concurrency limit.
You can delete the lambda function as soon as you realize what’s going on. Theoretically, new functions should not be able to launch and any existing ones would time out - I have not tested or confirmed this.
In summary:
- If a miscreant can gain access to your AWS account with permissions to create an IAM role and a Lambda function...
- within 5 minutes they can create an exponentially self-replicating lambda function that can rack up costs of around $2.94 / minute ($176.40 / hour) for at least 15 minutes, and have a DOS like effect on any serverless solutions you have in this account.
- There are no controls to stop this automatically, another great reason to make sure you have budget alerts enabled!
- Deleting the lambda function should stop the running functions from launching new copies and the already running functions will end after the timeout.
- As other cloud providers have similar services, I would expect them to have the same risk.
The calculation is: 1000 concurrency X 0.0029382 (lambda per-minute cost for 3GB memory) = $2.9382 / minute. This does not include cost for requests as I have not tested this in my account so I don’t know how many requests the Lambda function would be able to achieve in a loop (or if you still pay for requests that fail due to concurrency limits?). It also does not factor in the free tier but this would be spent within 3 minutes, or faster if you have active projects running in the account.
If anyone wants to actually try this in their account, please let me know how it goes!