awslabs / aws-lambda-go-api-proxy

lambda-go-api-proxy makes it easy to port APIs written with Go frameworks such as Gin (https://gin-gonic.github.io/gin/ ) to AWS Lambda and Amazon API Gateway.
Apache License 2.0
1.06k stars 198 forks source link

Double-URL encoded headers #147

Open elgohr opened 2 years ago

elgohr commented 2 years ago

Scenario: Using github.com/awslabs/aws-lambda-go-api-proxy within github.com/aws/aws-lambda-go/lambda behind an multi_value_headers-enabled ALB

Issue: URL-Query Parameters can be double-url encoded. For example a /?from=2022-09-20T04:11:02 would be url-encoded by the browser to /?from=2022-09-20T04%3A11%3A02 (as %3A is the url-encoding of :). Because of https://github.com/awslabs/aws-lambda-go-api-proxy/blob/master/core/request.go#L164 this value is encoded again before it reaches the handler. Instead of from=2022-09-20T04%3A11%3A02 a double-url encoded value is passed to the handler: from=2022-09-20T04%3A11%253A02 (as %25 is the url-encoding of %).

Suggested solution: Using url.QueryUnescape before encoding, to see whether the query parameter is already encoded (this would result in err != nil).

elgohr commented 1 year ago

Happy anniversary! 🎉

choonkeat commented 2 months ago

Using url.QueryUnescape before encoding, to see whether the query parameter is already encoded (this would result in err != nil).

https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html

If you enable multi-value headers, the load balancer uses both cookies sent by the client and sends you an event that includes headers using multiValueHeaders. For example:

"multiValueHeaders": {
    "cookie": ["name1=value1", "name2=value2"],
    ...
},

If the query parameters are URL-encoded, the load balancer does not decode them. You must decode them in your Lambda function.

So there's no need to try to url.QueryUnescape them