Skip to content

Commit

Permalink
feat: imdsv1 fallback toggle (#4517)
Browse files Browse the repository at this point in the history
* feat: imdsv1 fallback toggle

* undo formatting
  • Loading branch information
kuhe authored Nov 2, 2023
1 parent 82a2ad5 commit ea1ef93
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changes/next-release/feature-IMDS-3a28eff9.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "feature",
"category": "IMDS",
"description": "IMDSv1 fallback toggle"
}
14 changes: 14 additions & 0 deletions lib/credentials/ec2_metadata_credentials.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,18 @@ interface EC2MetadataCredentialsOptions {
}
maxRetries?: number
logger?: Logger
/**
* Prevent IMDSv1 fallback.
*/
ec2MetadataV1Disabled?: boolean

/**
* profile name to check for IMDSv1 settings.
*/
profile?: string

/**
* optional file from which to to get config.
*/
filename?: string
}
1 change: 1 addition & 0 deletions lib/credentials/ec2_metadata_credentials.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ require('../metadata_service');
* maxRetries: 10, // retry 10 times
* retryDelayOptions: { base: 200 }, // see AWS.Config for information
* logger: console // see AWS.Config for information
* ec2MetadataV1Disabled: false // whether to block IMDS v1 fallback.
* });
* ```
*
Expand Down
17 changes: 16 additions & 1 deletion lib/metadata_service.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,19 @@ interface MetadataServiceOptions {
* A set of options to configure the retry delay on retryable errors. See AWS.Config for details.
*/
retryDelayOptions?: any
}

/**
* Prevent IMDSv1 fallback.
*/
ec2MetadataV1Disabled?: boolean

/**
* profile name to check for IMDSv1 settings.
*/
profile?: string

/**
* optional file from which to to get config.
*/
filename?: string
}
36 changes: 36 additions & 0 deletions lib/metadata_service.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,18 @@ AWS.MetadataService = inherit({
* perform for timeout errors
* @option options retryDelayOptions [map] A set of options to configure the
* retry delay on retryable errors. See AWS.Config for details.
* @option options ec2MetadataV1Disabled [boolean] Whether to block IMDS v1 fallback.
* @option options profile [string] A profile to check for IMDSv1 fallback settings.
* @option options filename [string] Optional filename for the config file.
*/
constructor: function MetadataService(options) {
if (options && options.host) {
options.endpoint = 'http://' + options.host;
delete options.host;
}
this.profile = options && options.profile || process.env.AWS_PROFILE || AWS.util.defaultProfile;
this.ec2MetadataV1Disabled = !!(options && options.ec2MetadataV1Disabled);
this.filename = options && options.filename;
AWS.util.update(this, options);
},

Expand Down Expand Up @@ -146,6 +152,36 @@ AWS.MetadataService = inherit({
var self = this;
var basePath = '/latest/meta-data/iam/security-credentials/';

var isImdsV1Fallback = self.disableFetchToken
|| !(options && options.headers && options.headers['x-aws-ec2-metadata-token']);

if (isImdsV1Fallback && !(process.env.AWS_EC2_METADATA_DISABLED)) {
try {
var profiles = AWS.util.getProfilesFromSharedConfig(AWS.util.iniLoader, this.filename);
var profileSettings = profiles[this.profile] || {};
} catch (e) {
profileSettings = {};
}

if (profileSettings.ec2_metadata_v1_disabled && profileSettings.ec2_metadata_v1_disabled !== 'false') {
return cb(AWS.util.error(
new Error('AWS EC2 Metadata v1 fallback has been blocked by AWS config file profile.')
));
}

if (self.ec2MetadataV1Disabled) {
return cb(AWS.util.error(
new Error('AWS EC2 Metadata v1 fallback has been blocked by AWS.MetadataService::options.ec2MetadataV1Disabled=true.')
));
}

if (process.env.AWS_EC2_METADATA_V1_DISABLED && process.env.AWS_EC2_METADATA_V1_DISABLED !== 'false') {
return cb(AWS.util.error(
new Error('AWS EC2 Metadata v1 fallback has been blocked by process.env.AWS_EC2_METADATA_V1_DISABLED.')
));
}
}

self.request(basePath, options, function (err, roleName) {
if (err) {
self.disableFetchToken = !(err.statusCode === 401);
Expand Down

0 comments on commit ea1ef93

Please sign in to comment.