getSignedUrl not always returning a valid signed-url
See original GitHub issueConfirm by changing [ ] to [x] below to ensure that it’s a bug:
- I’ve gone through Developer Guide and API reference
- I’ve checked AWS Forums and StackOverflow for answers
- I’ve searched for previous similar issues and didn’t find any solution
Describe the bug
Sometimes when calling s3.getSignedUrl(method, params)
we receive an invalid signed URL from the SDK and no error is thrown. EG:https://s3.us-west-2.amazonaws.com/
This happens on both getObject and putObject methods, and retrying the call produces the expected results.
Is the issue in the browser/Node.js? Node.js
If on Node.js, are you running this on AWS Lambda? No Details of the browser/Node.js version Node v10.21.0
SDK version number v2.694.0
To Reproduce (observed behavior) Excerpt from our code
const AWS = require('aws-sdk');
const path = require('path');
const log = require('../logger');
const config = require('config');
const bucket = config.s3.uploads.bucket;
const region = config.s3.uploads.region;
const s3 = new AWS.S3({
apiVersion: '2006-03-01',
signatureVersion: 'v4',
region
});
async function getSignedUrl(method, params) {
try {
const preSignedUrl = s3.getSignedUrl(method, params);
if (!preSignedUrl.includes("X-Amz-Signature")) {
log.error(`received a non valid ${method} presigned url : ${preSignedUrl}`);
throw new Error ("Illegal presigned url returned!");
}
return preSignedUrl;
} catch (err) {
log.error(err, `Error retrieving ${method} pre-signed url`);
throw err;
}
}
Params being:
const uploadlinkparams = {
Key: prefix,
Bucket: bucket,
Expires: 60 * 60, // one hour
Tagging: "" // This header needs to exist otherwise we can't add tags
};
const downloadlinkparams = {
Key: prefix,
Bucket: bucket,
Expires: downloadttl ? downloadttl * 60 : 60 * 60 * 24 * 7 // 7 days if not specified
};
Expected behavior We expect to receive a valid pre-signed url, or an error to be thrown by the SDK
Screenshots N/A
Additional context This code runs on EC2 instances. I cannot reproduce locally outside of AWS. It is hard to reproduce in AWS.
We see the following calls made before the failure: PUT //169.254.169.254/latest/api/token [200] GET //169.254.169.254/latest/meta-data/iam/security-credentials/ [200] GET //169.254.169.254/latest/meta-data/iam/security-credentials/<censored>InstanceProfile [200]
With the failure message being: received a non valid putObject presigned url : https://s3.us-west-2.amazonaws.com/
Issue Analytics
- State:
- Created 3 years ago
- Reactions:3
- Comments:18 (4 by maintainers)
Commenting to keep this open
As of today, it seems like a call to this function (promise or not) returns the bare legacy
https://s3.amazonaws.com/
while onlyhttps://s3.[region].amazonaws.com/
is allowed.