Skip to content

Commit

Permalink
Alibaba ram user access keys rotation plugin with spec file (aquasecu…
Browse files Browse the repository at this point in the history
…rity#722)

* Alibaba plugin added for ram user access keys rotation with spec files

* Messages updated

* Lint error fixed

* Update plugins/alibaba/ram/accessKeysRotation.js

Co-authored-by: AkhtarAmir <makhtar.pucit@gmail.com>
Co-authored-by: Gio Rodriguez <gioroddev@gmail.com>
  • Loading branch information
3 people authored May 28, 2021
1 parent b67f778 commit e61b78e
Show file tree
Hide file tree
Showing 4 changed files with 237 additions and 0 deletions.
7 changes: 7 additions & 0 deletions collectors/alibaba/collector.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ var postcalls = [
filterValue: ['UserName'],
apiVersion: '2015-05-01'
},
ListAccessKeys: {
reliesOnService: 'ram',
reliesOnCall: 'ListUsers',
filterKey: ['UserName'],
filterValue: ['UserName'],
apiVersion: '2015-05-01'
},
ListPoliciesForUser: {
reliesOnService: 'ram',
reliesOnCall: 'ListUsers',
Expand Down
1 change: 1 addition & 0 deletions exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,7 @@ module.exports = {
'inactiveUserDisabled' : require(__dirname + '/plugins/alibaba/ram/inactiveUserDisabled.js'),
'passwordRequiresUppercase' : require(__dirname + '/plugins/alibaba/ram/passwordRequiresUppercase.js'),
'usersMfaEnabled' : require(__dirname + '/plugins/alibaba/ram/usersMfaEnabled.js'),
'accessKeysRotation' : require(__dirname + '/plugins/alibaba/ram/accessKeysRotation.js'),
'passwordNoReuse' : require(__dirname + '/plugins/alibaba/ram/passwordNoReuse.js'),
'passwordExpiry' : require(__dirname + '/plugins/alibaba/ram/passwordExpiry.js'),
'passwordBlockLogon' : require(__dirname + '/plugins/alibaba/ram/passwordBlockLogon.js'),
Expand Down
88 changes: 88 additions & 0 deletions plugins/alibaba/ram/accessKeysRotation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
var helpers = require('../../../helpers/alibaba');

module.exports = {
title: 'Access Keys Rotation',
category: 'RAM',
description: 'Ensure that RAM user access keys are rotated after regular interval of time.',
more_info: 'Access keys should be rotated to avoid having them accidentally exposed.',
link: 'https://www.alibabacloud.com/help/doc-detail/152682.htm',
recommended_action: 'Rotate the access keys every desired number of days',
apis: ['RAM:ListUsers', 'RAM:ListAccessKeys', 'STS:GetCallerIdentity'],
settings: {
ram_access_keys_rotation_interval: {
name: 'RAM User Access Keys Rotation Interval',
description: 'Return a failing result when access keys exceed this number of days without being rotated',
regex: '^[1-9]{1}[0-9]{0,3}$',
default: '90'
}
},

run: function(cache, settings, callback) {
var results = [];
var source = {};

var accessKeyRotationInterval = parseInt(settings.ram_access_keys_rotation_interval || this.settings.ram_access_keys_rotation_interval.default);
var region = helpers.defaultRegion(settings);
var accountId = helpers.addSource(cache, source, ['sts', 'GetCallerIdentity', region, 'data']);
var listUsers = helpers.addSource(cache, source,
['ram', 'ListUsers', region]);

if (!listUsers) return callback(null, results, source);

if (listUsers.err || !listUsers.data) {
helpers.addResult(results, 3,
'Unable to query RAM users' + helpers.addError(listUsers), region);
return callback(null, results, source);
}

if (!listUsers.data.length) {
helpers.addResult(results, 0, 'No RAM users found', region);
return callback(null, results, source);
}

for (var user of listUsers.data) {
if (!user.UserName) continue;

var getAccessKey = helpers.addSource(cache, source,
['ram', 'ListAccessKeys', region, user.UserName]);

if (getAccessKey.err || !getAccessKey.data) {
helpers.addResult(results, 3,
'Unable to query user access keys' + helpers.addError(getAccessKey), region);
continue;
}

let resource = helpers.createArn('ram', accountId, 'user', user.UserName);
if (getAccessKey.data.AccessKeys && getAccessKey.data.AccessKeys.AccessKey && getAccessKey.data.AccessKeys.AccessKey.length) {
let activeKeyFound = false;
for (var accessKey of getAccessKey.data.AccessKeys.AccessKey) {
if (accessKey.Status && accessKey.Status == 'Active') {
activeKeyFound = true;
resource = resource + ':' + accessKey.AccessKeyId;
let createDate = accessKey.CreateDate;
var currentDate = new Date();
var createDateFormat = new Date(createDate);

var diffInDays = helpers.daysBetween(currentDate, createDateFormat);
if (diffInDays <= accessKeyRotationInterval) {
helpers.addResult(results, 0,
`RAM user access key was last rotated ${diffInDays} days ago which is equal to or less than ${accessKeyRotationInterval}`, region, resource);
} else {
helpers.addResult(results, 2,
`RAM user access key was last rotated ${diffInDays} days ago which is greater than ${accessKeyRotationInterval}`, region, resource);
}
}
}
if (!activeKeyFound) {
helpers.addResult(results, 0,
'RAM user does not have any active access keys', region, resource);
}
} else {
helpers.addResult(results, 0,
'RAM user does not have any access keys', region, resource);
}
}

callback(null, results, source);
}
};
141 changes: 141 additions & 0 deletions plugins/alibaba/ram/accessKeysRotation.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
var expect = require('chai').expect;
var helpers = require('../../../helpers/alibaba');
var accessKeysRotation = require('./accessKeysRotation')

var passDate = new Date();
passDate.setMonth(passDate.getMonth() - 2);
var failDate = new Date();
failDate.setMonth(failDate.getMonth() - 7);

const listUsers = [
{
"UserName": "aqua",
"UserId": "254529020129829608",
},
{
"UserName": "cloudsploit",
"UserId": "283806919721151694",
}
];

const getUserLoginProfile = [
{
AccessKeys: {
AccessKey: [
{
Status: "Active",
AccessKeyId: "LTAI5tD6ekrSssrWq5rNa4JQ",
CreateDate: failDate,
},
],
},
},
{
AccessKeys: {
AccessKey: [
{
Status: "Active",
AccessKeyId: "LTAI5tD6ekrSssrWq5rNa4JQ",
CreateDate: passDate,
},
],
},
},
{
AccessKeys: {
AccessKey: [],
},
}
];

const createCache = (users, accessKeys, accessKeysError, error) => {
let userName = (users && users.length) ? users[0].UserName : null;
return {
ram: {
ListUsers: {
'cn-hangzhou': {
data: users,
err: error
}
},
ListAccessKeys: {
'cn-hangzhou': {
[userName]: {
data: accessKeys,
err: accessKeysError
}
}
},
}
}
}

describe('accessKeysRotation', function () {
describe('run', function () {
it('should FAIL if RAM user access keys are not rotated every 90 days or less', function (done) {
const cache = createCache([listUsers[0]], getUserLoginProfile[0], null, null);
accessKeysRotation.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(2);
expect(results[0].message).to.include('which is greater than');
expect(results[0].region).to.equal('cn-hangzhou');
done();
});
});

it('should PASS if RAM user access keys are not rotated every 90 days or less', function (done) {
const cache = createCache([listUsers[0]], getUserLoginProfile[1], null, null);
accessKeysRotation.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('which is equal to or less than');
expect(results[0].region).to.equal('cn-hangzhou');
done();
});
});

it('should PASS if RAM user does not have any access keys', function (done) {
const cache = createCache([listUsers[1]], getUserLoginProfile[2], null, null);
accessKeysRotation.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('RAM user does not have any access keys');
expect(results[0].region).to.equal('cn-hangzhou');
done();
});
});

it('should PASS if No RAM users found', function (done) {
const cache = createCache([]);
accessKeysRotation.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('No RAM users found');
expect(results[0].region).to.equal('cn-hangzhou');
done();
});
});

it('should UNKNOWN if unable to query user access keys', function (done) {
const cache = createCache([listUsers[0]], null, [], null);
accessKeysRotation.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(3);
expect(results[0].message).to.include('Unable to query user access keys');
expect(results[0].region).to.equal('cn-hangzhou');
done();
});
});

it('should UNKNOWN if unable to query RAM users', function (done) {
const cache = createCache(null, null, null, null);
accessKeysRotation.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(3);
expect(results[0].message).to.include('Unable to query RAM users');
expect(results[0].region).to.equal('cn-hangzhou');
done();
});
});
})
})

0 comments on commit e61b78e

Please sign in to comment.