aws4
aws4 copied to clipboard
Specifying port explicitly in options breaks "string to sign"
Hi! First, thanks for creating this module, it has made my development life a lot easier. For such a valuable function, I'm surprised its not in the aws-sdk (or maybe it is, and I just can't find it :) )
I recently ran into an issue where I was signing HTTPS requests that were attempting to push data into AWS Elasticsearch from a lambda. My policy restricted POSTs and PUTs to the role my lambda was operating under. So far so good.
I used the library to sign requests, but kept getting HTTP 403 responses, with a message saying "The request signature we calculated does not match the signature you provided..."
After playing with what I had in my request options for a bit and combing through logs, I found that I had explicitly set the "port" property of my request options to 443 prior to signing it.
When I removed the port option, the request was properly signed and my index requests started returning HTTP 200.
From my logs, it looked like the aws4 lib was including the port as part of the "String to sign", but AWS was excluding it.
It might be the case that since 443 is the standard https port, AWS erroneously drops the port from the string to sign, or maybe Node.js drops it from the actual request, or maybe aws4 problematically includes it in the host before signing... I haven't delved quite that far yet. Wondering if you've run into this situation before?
I was able to keep working a bit and explored Node HTTP module behavior.
Details are recorded in this gist: https://gist.github.com/brnkrygs/a96869ee9b02ab8916c933e09a8a8381
From my (admittedly limited) testing, it looks like the Node HTTP module drops the port from the request info if its a 'standard' port for the given protocol.
Applying that to this module, it looks like since my requests were HTTPS for port 443, having the 443 included in the string to sign by the module caused the signature mis-match, since Node never actually included that in the real request.
Maybe a fix would be to exclude port
from the string to sign if it matches the 'standard' port for the configured protocol?