How can I ensure requests to URLs with whatever (bad) query string data in them, make it to my lambda behind api gateway and not be blocked at api gateway?
I have an endpoint on API gateway which responds to requests such as the one below where the query string parameter url should exist.
https://the-api-id.amazonaws.com?url=https://stackoverflow.com
The query string parameter url receives a URL which is usually url encoded so not a problem. Other times the URL arrives unencoded and therefore potentially non URL safe characters are present.
Unfortunately I am downstream from other services which occasionally send me bad data and one of the responsibilities of this particular hop is to detect and attempt to rectify/clean it. I cannot prevent the request to my API gateway endpoint containing non url safe characters.
The problem is such that if bad data exists in the URL, it would appear that API gateway rejects the request and doesn't forward it to my lambda even though it's using Lambda Proxy and I've not set up anything I'm aware of at the api gateway level to stop requests going through.
If you takes the serverless framework example at the bottom of this question, it can be easily reproduced.
Simply deploy then visit
And you'll see the expected text/html response.
However, if you were to visit the following where I've put { and } in, unencoded (as is commonly received by my endpoint) you'll see that API gateway returns a 400 status response and doesn't appear to forward the request to the lambda function.
https://the-api-id.execute-api.us-east-1.amazonaws.com/dev/?url={clickurl}
I ticked "Enable CloudWatch Logs" in the api gateway console, and a log group was created but it doesn't appear to get any records so that appears to be a dead end.
I have tried regional and edge optimised endpoints and both api gateway and cloudfront respond with the same thing.
How can I ensure requests to URLs with whatever (bad) query string data in them, make it to my lambda behind api gateway and not be blocked at api gateway?
Below is just boilerplate to play around with a working example using the serverless framework if you were so inclined.
serverless.yml
---
service: example-400
frameworkVersion: '2'
provider:
name: aws
runtime: nodejs12.x
functions:
hello:
handler: handler.hello
events:
- http:
path: /
method: get
handler.js
'use strict';
module.exports.hello = async event => {
return {
statusCode: 200,
body: JSON.stringify(
{
message: 'Go Serverless v1.0! Your function executed successfully!',
input: event,
},
null,
2
),
};
};
Then run
serverless deploy