Open bhatiasuraj opened 5 years ago
AFAIR, HOST header value is not utilized in signature calculation
On Aug 28, 2019, at 9:34 AM, Suraj Bhatia notifications@github.com wrote:
Created a private API with API Gateway and enabled AWS_IAM auth on a GET method for a resource. When invoking using the default Stage URL (using private DNS name), the request works fine as below -
awscurl -v https://API-ID.execute-api.REGION.amazonaws.com/STAGE/RESOURCE
However, making a request using the public DNS names leads to the signature calculation error. We are passing the Host header here for the VPC endpoint to be able to identify which API to hit.
awscurl -v https://vpce-ID.execute-api.REGION.vpce.amazonaws.com/STAGE/RESOURCE -H "Host: API-ID.execute-api.REGION.amazonaws.com"
If we replace Host header with x-api-gw-id as suggested here https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-api-test-invoke-url.html#w20aac13c16c28c11
The request works fine -
awscurl -v https://vpce-ID.execute-api.REGION.vpce.amazonaws.com/STAGE/RESOURCE -H "x-apigw-api-id: API-ID"
I suspect the issue is with how the host header value is used in the signature calculation. Can you please confirm if format is right?
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.
Why is there a signature calculation error in that case then?
# If the host was specified in the HTTP header, ensure that the canonical
# headers are set accordingly
if 'host' in headers:
fullhost = headers['host']
else:
fullhost = host + ':' + port if port else host
i see -- is that case sensitivity behavior, what happens if you specify with lower case?
Voila! Using 'host' instead of 'Host' leads to 200 response. Not cool though, right?
prioritizing to get you going, so it's cool you are unblocked.
so now should decide what's the right way going forward -- do you want to take a crack at that?
Yeah, fortunately x-api-gw-id works so I'm unblocked. I can take a look it though
Have a look - too heads are better than one
On Aug 28, 2019, at 11:33 AM, Suraj Bhatia notifications@github.com wrote:
Yeah, fortunately x-api-gw-id works so I'm unblocked. I can take a look it though
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.
@okigan This change should be sufficient (line85 on wards) -
if 'Host' in headers:
host = headers['Host']
else:
host = uri_dict['host']
Basically checking if a "Host" header was explicitly passed in the URL, if so - override 'host' with that value instead of picking it from the URL dictionary.
Tested with below URLs -
1. Private DNS name of the API and no Host header explicitly passed $ awscurl https://API-ID.execute-api.REGION.amazonaws.com/STAGE/RESOURCE Success
2. Public DNS name of the API with Host header specified as "Host" $ awscurl https://vpce-ID.execute-api.REGION.vpce.amazonaws.com/STAGE/RESOURCE -H "Host: API-ID.execute-api.REGION.amazonaws.com" Success
3. Public DNS name of the API with Host header specified as "host" $ awscurl https://vpce-ID.execute-api.REGION.vpce.amazonaws.com/STAGE/RESOURCE -H "host: API-ID.execute-api.REGION.amazonaws.com" Success
i think using dictionary with case insensitive lookup is more full prof -- requests library includes one - what do you think about using that one?
That would require more changes - currently host is being picked up from the URL and not the headers.
i forget - would this be sufficient, or it's missing something?
@bhatiasuraj bumping this up -- check out #72
Created a private API with API Gateway and enabled AWS_IAM auth on a GET method for a resource. When invoking using the default Stage URL (using private DNS name), the request works fine as below -
awscurl -v https://API-ID.execute-api.REGION.amazonaws.com/STAGE/RESOURCE
However, making a request using the public DNS names leads to the signature calculation error. We are passing the Host header here for the VPC endpoint to be able to identify which API to hit.
awscurl -v https://vpce-ID.execute-api.REGION.vpce.amazonaws.com/STAGE/RESOURCE -H "Host: API-ID.execute-api.REGION.amazonaws.com"
If we replace Host header with x-api-gw-id as suggested here https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-api-test-invoke-url.html#w20aac13c16c28c11
The request works fine -
awscurl -v https://vpce-ID.execute-api.REGION.vpce.amazonaws.com/STAGE/RESOURCE -H "x-apigw-api-id: API-ID"
I suspect the issue is with how the host header value is used in the signature calculation. Can you please confirm if format is right?