Secure AWS API Gateway with Lambda Integration - amazon-web-services

I am creating a publicly available API using API Gateway which is backed with lambda functions to do some processing. I have secured it with a custom security header that implements hmac authentication with timestamp to protect against replay attacks.
I understand that API Gateway protects against DDOS attacks through its high availability, but any invalid requests will still be passed to the lambda authentication function. So, I guess an attacker can submit invalid unauthenticated requests resulting in high costs. It will take a considerable number of requests to cause damage but it is still very doable. What is the best way to protect against that ?
Thank you

To prevent DDoS and higher rate of access, you can setup WAF. Have a look at this link, to get a deeper understanding how to setup WAF with API Gateway.

API Gateway will not charge you for unauthenticated requests, however you would be charged by Lambda for the invocation on the authorizer.
API Gateway offers a semi-useful mitigation to this problem in the form of the 'identity validation expression' on the Authorizer, which is just a regex that is matched against the incoming identity source header.
Besides that, you might want to just implement some kind of negative cache or validation yourself in the Authorizer function to minimize the billed milliseconds.

Related

How can I prevent that bots are generating costs at my AWS Lambda Function

I was planning a concept for my mobile Game and using AWS Lambda (or Firebase Functions where its the same). Couldn't a bot permanently do a request to my Lambda-Function and generate massive costs by only spamming my Endpoint?
Is there any protection from Amazon / Google or how would you guys secure you Endpoint for this kind of attacks?
See Protecting API Endpoints, and more generally read AWS Best Practices for DDoS Resiliency.
You would use a combination of:
API Gateway (with authenticated clients and, potentially, throttling)
CloudFront
WAF

Should I use Custom Authorizer or Lambda#edge to secure my API

I want to lock down my API and I am wondering the best way to do this.
I have approx 20 micro services that are using API gateway with a proxy that has a custom authorizer. This has a cloudfront distribution.
The issue with sending through an authorisation token (bearer) is that I am not getting the caching benefits of cloudfront for every new user. Therefore I am subject to two sets of cold starts which makes cloudfront pointless.
Should I switch to a lambda#edge authorisation method or should I continue with a custom authorizer. I would like to know the benefits of either approach. There is concern that if we use lambda#edge authorisation technique then we are leaving the proxy api (non cloudfront) wide open.
Thanks for your help!

How to set quota for CORS preflight requests with AWS API Gateway

I'm building a serverless application with AWS Lambda and API Gateway. In order to prevent DDOS attacks doing a large number of requests costing me lots of money, I've set up a usage plan with a request quota (e.g. 10K requests/month). This requires an API key to be passed as header by callers.
This seemingly works well, but I also need to enable CORS for this service. For that I need to allow for an unauthorized OPTIONS request ("CORS preflight" request) as browsers don't support sending any special header there. But then I can't seem to find a way for enforcing a quota and I'm back to square one: an uncontrolled number of those requests could cost an unforeseeable amount of money. Is there any way to exclude this possibility?
To enforce a quota on OPTIONS requests, create a web ACL in AWS WAF & associate it to a stage of your API in API Gateway. Add a rate-based rule in the web ACL that blocks all OPTIONS requests beyond the rate limit you specify. Rules in web ACLs can be configured specifically for this, as shown below:
For a screenshot-guided tutorial of this entire process, see my blog post.
You are not paying for any unauthorized calls to API-Gateway.
AWS is picking up this charge.
You are paying after the request is authorized and only if it does not exceed your usage plan.
So if somebody is doing a DDOS on your API without authentication it is free of charge.
If somebody is doing a DDOS with a valid api key you will only pay until your usage plan is exceeded.
Find more information here.
Requests are not charged for authorization and authentication
failures.
Calls to methods that require API keys are not charged when API keys
are missing or invalid.
API Gateway-throttled requests are not charged when the request rate
or burst rate exceeds the preconfigured limits.
Usage plan-throttled requests are not charged when rate limits or
quota exceed the preconfigured limits.
So make sure to have authentication enabled on your API and a usage plan in place for all the authenticated requests.

How do we address/what are good practices for "serverless" resource abuse?

If I create a public endpoint using AWS API Gateway, the entire world could access it. This would be a problem because the end point would trigger an AWS Lambda function. If we assume that I can't query a data source to determine the frequency that the incoming IP address queried the resource in the past, what would be the best practice for protecting this end point from abuse? Do I have any other security options?
I realize I could use a reCaptcha but this would still invoke the AWS Lambda function and would incur costs if done a million times over a short window of time.
A very simple way of protecting your API gateway
Use AWS Cloudfront with TTL 0 and pass custom headers from AWS Cloudfront to API gateway
Use AWS WAF with AWS Cloudfront
AWS API Gateway also handles some basic level of DDOS attacks.
Kindly also view these blogs for securing AWS API Gateway
https://aws.amazon.com/blogs/compute/protecting-your-api-using-amazon-api-gateway-and-aws-waf-part-i/
https://aws.amazon.com/blogs/compute/protecting-your-api-using-amazon-api-gateway-and-aws-waf-part-2/
You are probably looking for throttling limit configuration or usage plan definition:
To prevent your API from being overwhelmed by too many requests,
Amazon API Gateway throttles requests to your API using the token
bucket algorithm, where a token counts for a request. Specifically,
API Gateway sets a limit on a steady-state rate and a burst of request
submissions against all APIs in your account. In the token bucket
algorithm, the burst is the maximum bucket size.
When request submissions exceed the steady-state request rate and
burst limits, API Gateway fails the limit-exceeding requests and
returns 429 Too Many Requests error responses to the client. Upon
catching such exceptions, the client can resubmit the failed requests
in a rate-limiting fashion, while complying with the API Gateway
throttling limits.
As an API developer, you can set the limits for individual API stages
or methods to improve overall performance across all APIs in your
account. Alternatively, you can enable usage plans to restrict client
request submissions to within specified request rates and quotas. This
restricts the overall request submissions so that they don't go
significantly past the account-level throttling limits.
References:
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-usage-plans-with-console.html#api-gateway-usage-plan-create

Prevent AWS Lambda flooding

I'm considering about moving my service from a VPS to AWS Lambda + DynamoDB to use it as a FaaS, because it's basically 2 API GET calls that fetch info from the database and serve it, and the normal use of those API calls are really rare (about 50 times a week)
But it makes me wonder... As I can't setup a limit on how many calls I want to serve each month, some attacker could theoretically flood my service by calling it a couple thousands times a day and make my AWS bill extremely expensive. Setting up a limit per month wouldn't be a nice idea either, because the attacker could flood the first day and I won't have more requests to serve. The ideal thing would be to set up a limit on request rate per client.
Anyone knows how could I protect it? I've seen that AWS also offers a Firewall, but that's for CloudFront. Isn't there any way to make it work with Lambda directly?
You can put AWS CloudFront in front API Gateway and Lambda so that, the traffic will be served to outside through CloudFront.
In addition by configuring AWS WAF with rate base blocking, it is possible to block high frequencies of access by attackers.
However when configuring AWS CloudFront in front of API Gateway and Lambda, you also need to restrict direct access to API Gateway (Since API Gateway will be publicly accessible by default). This can be achieved in following ways.
Enable API Keys for API Gateway and use the API Key in AWS CloudFront Headers in the Origin.
Use a Token Header and Verify it using a Custom Authorizer Lambda function.
Two options spring to mind:
place API Gateway in front of Lambda so that API requests
have to be authenticated. API Gateway also has built-in throttles and other useful features.
invoke the Lambda directly, which will require the client
invoking the Lambda to have the relevant IAM credentials.