aws sigv4 signature not match when Content-Length exist in the request before applying AmazonConnection
Closed this issue · 0 comments
There is a bug in AmazonConnection.js where it does not detect whether content-length header exists in the request before adding a content-length header.
header before adding content-length:
"headers": {
"User-Agent": "elasticsearch-js/5.6.22 (darwin 18.7.0-x64; Node.js v14.9.0)",
"Content-Length": "0",
"host": "my-service.us-east-1.es.amazonaws.com"
},
after this code (this code seems OK as http header is case insensitive, however aws4 library might not know how to handle it)
if (params.body) {
req.headers['content-length'] = Buffer.byteLength(params.body, 'utf8')
req.body = params.body
} else {
req.headers['content-length'] = 0
}
headers become:
"headers": {
"User-Agent": "elasticsearch-js/5.6.22 (darwin 18.7.0-x64; Node.js v14.9.0)",
"Content-Length": "0",
"host": "my-service.us-east-1.es.amazonaws.com",
"content-length": 0
},
signature contains both Content-Length and content-length, will cause signature errors.
SignedHeaders=content-length;content-length;host;user-agent;x-amz-date;x-amz-security-token, Signature=xx
response:
"body": {
"message": "The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."
},
"statusCode": 403,
To test this is the case,
I changed the code to use 'Content-Length' and it then worked.
if (params.body) {
req.headers['Content-Length'] = Buffer.byteLength(params.body, 'utf8')
req.body = params.body
} else {
req.headers['Content-Length'] = 0
}