Skip to content

Commit 4af0f44

Browse files
Revised keyVaultKeyExpiry (aquasecurity#2105)
* Revised keyVaultKeyExpiry * Revised keyVaultKeyExpiry * Apply suggestions from code review * Update plugins/azure/keyvaults/keyVaultKeyExpiry.js * Update keyVaultKeyExpiry.js * Update keyVaultKeyExpiry.spec.js * Apply suggestions from code review * Update plugins/azure/keyvaults/keyVaultKeyExpiry.spec.js * Update plugins/azure/keyvaults/keyVaultKeyExpiry.spec.js * Update plugins/azure/keyvaults/keyVaultKeyExpiry.spec.js --------- Co-authored-by: AkhtarAmir <AkhtarAmir> Co-authored-by: alphadev4 <113519745+alphadev4@users.noreply.github.com>
1 parent f75a336 commit 4af0f44

File tree

2 files changed

+60
-77
lines changed

2 files changed

+60
-77
lines changed

plugins/azure/keyvaults/keyVaultKeyExpiry.js

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ var async = require('async');
22
var helpers = require('../../../helpers/azure');
33

44
module.exports = {
5-
title: 'Key Vault Key Expiry',
5+
title: 'Key Vault Key Expiry RBAC',
66
category: 'Key Vaults',
77
domain: 'Application Integration',
88
severity: 'High',
9-
description: 'Proactively check for Key Vault keys expiry date and rotate them before expiry date is reached.',
10-
more_info: 'After expiry date has reached for Key Vault key, it cannot be used for cryptographic operations anymore.',
11-
recommended_action: 'Ensure that Key Vault keys are rotated before they get expired.',
9+
description: 'Ensures that expiration date is set for all keys in RBAC Key Vaults.',
10+
more_info: 'Setting an expiration date on keys helps in key lifecycle management and ensures that keys are rotated regularly.',
11+
recommended_action: 'Modify keys in RBAC Key Vaults to have an expiration date set.',
1212
link: 'https://learn.microsoft.com/en-us/azure/key-vault/about-keys-secrets-and-certificates',
1313
apis: ['vaults:list', 'vaults:getKeys'],
1414
settings: {
@@ -45,38 +45,46 @@ module.exports = {
4545
return rcb();
4646
}
4747

48-
vaults.data.forEach(function(vault){
48+
vaults.data.forEach(function(vault) {
49+
if (!vault || !vault.properties) {
50+
helpers.addResult(results, 3, 'Unable to read vault properties', location, vault.id);
51+
return;
52+
}
53+
if (!vault.properties.enableRbacAuthorization) {
54+
return;
55+
}
56+
4957
var keys = helpers.addSource(cache, source,
5058
['vaults', 'getKeys', location, vault.id]);
5159

5260
if (!keys || keys.err || !keys.data) {
5361
helpers.addResult(results, 3, 'Unable to query for Key Vault keys: ' + helpers.addError(keys), location, vault.id);
5462
} else if (!keys.data.length) {
55-
helpers.addResult(results, 0, 'No Key Vault keys found', location, vault.id);
63+
helpers.addResult(results, 0, 'No Key Vault keys found in RBAC vault', location, vault.id);
5664
} else {
5765
keys.data.forEach(function(key) {
5866
var keyName = key.kid.substring(key.kid.lastIndexOf('/') + 1);
5967
var keyId = `${vault.id}/keys/${keyName}`;
6068

6169
if (!key.attributes || !key.attributes.enabled) {
6270
helpers.addResult(results, 0,
63-
'Key is not enabled', location, keyId);
71+
'Key in RBAC vault is not enabled', location, keyId);
6472
} else if (key.attributes && (key.attributes.expires || key.attributes.exp)) {
6573
let keyExpiry = key.attributes.exp ? key.attributes.exp * 1000 : key.attributes.expires;
6674
let difference = Math.round((new Date(keyExpiry).getTime() - (new Date).getTime())/(24*60*60*1000));
6775
if (difference > config.key_vault_key_expiry_fail) {
6876
helpers.addResult(results, 0,
69-
`Key expires in ${difference} days`, location, keyId);
77+
`Key in RBAC vault expires in ${difference} days`, location, keyId);
7078
} else if (difference > 0){
7179
helpers.addResult(results, 2,
72-
`Key expires in ${difference} days`, location, keyId);
80+
`Key in RBAC vault expires in ${difference} days`, location, keyId);
7381
} else {
7482
helpers.addResult(results, 2,
75-
`Key expired ${Math.abs(difference)} days ago`, location, keyId);
83+
`Key in RBAC vault expired ${Math.abs(difference)} days ago`, location, keyId);
7684
}
7785
} else {
7886
helpers.addResult(results, 0,
79-
'Key expiration is not enabled', location, keyId);
87+
'Key expiration is not enabled in RBAC vault', location, keyId);
8088
}
8189
});
8290
}

plugins/azure/keyvaults/keyVaultKeyExpiry.spec.js

Lines changed: 41 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -12,96 +12,71 @@ keyExpired.setMonth(keyExpired.getMonth() - 1);
1212

1313
const listKeyVaults = [
1414
{
15-
id: '/subscriptions/abcdfget-ebf6-437f-a3b0-28fc0d22111e/resourceGroups/akhtar-rg/providers/Microsoft.KeyVault/vaults/nauman-test',
16-
name: 'nauman-test',
15+
id: '/subscriptions/123/resourceGroups/test-rg/providers/Microsoft.KeyVault/vaults/test-vault',
16+
name: 'test-vault',
1717
type: 'Microsoft.KeyVault/vaults',
1818
location: 'eastus',
19-
tags: { owner: 'kubernetes' },
20-
sku: { family: 'A', name: 'Standard' },
21-
tenantId: '2d4f0836-5935-47f5-954c-14e713119ac2',
22-
accessPolicies: [
23-
{
24-
tenantId: '2d4f0836-5935-47f5-954c-14e713119ac2',
25-
objectId: 'b4062000-c33b-448b-817e-fa0f17bef4b9',
26-
permissions: {
27-
keys: ['Get', 'List'],
28-
secrets: ['Get', 'List'],
29-
certificates: ['Get', 'List']
30-
}
31-
}
32-
],
33-
enableSoftDelete: true,
34-
softDeleteRetentionInDays: 7,
35-
enableRbacAuthorization: false,
36-
vaultUri: 'https://nauman-test.vault.azure.net/',
37-
provisioningState: 'Succeeded'
38-
}
39-
];
40-
41-
const getKeys = [
19+
properties: {
20+
enableRbacAuthorization: true,
21+
vaultUri: 'https://test-vault.vault.azure.net/'
22+
}
23+
},
24+
{
25+
id: '/subscriptions/123/resourceGroups/test-rg/providers/Microsoft.KeyVault/vaults/test-vault-2',
26+
name: 'test-vault-2',
27+
type: 'Microsoft.KeyVault/vaults',
28+
location: 'eastus',
29+
properties: {
30+
enableRbacAuthorization: false,
31+
vaultUri: 'https://test-vault-2.vault.azure.net/'
32+
}
33+
}
34+
];
35+
36+
const getKeys = [
4237
{
4338
"attributes": {
4439
"created": "2022-04-10T17:57:43+00:00",
4540
"enabled": true,
4641
"expires": null,
4742
"notBefore": null,
48-
"recoveryLevel": "CustomizedRecoverable+Purgeable",
4943
"updated": "2022-04-10T17:57:43+00:00"
5044
},
51-
"kid": "https://nauman-test.vault.azure.net/keys/nauman-test",
52-
"managed": null,
53-
"name": "nauman-test",
54-
"tags": {
55-
"hello": "world"
56-
}
45+
"kid": "https://test-vault.vault.azure.net/keys/test-key",
46+
"name": "test-key"
5747
},
5848
{
5949
"attributes": {
6050
"created": "2022-04-10T17:57:43+00:00",
6151
"enabled": true,
6252
"expires": keyExpiryPass,
6353
"notBefore": null,
64-
"recoveryLevel": "CustomizedRecoverable+Purgeable",
6554
"updated": "2022-04-10T17:57:43+00:00"
6655
},
67-
"kid": "https://nauman-test.vault.azure.net/keys/nauman-test",
68-
"managed": null,
69-
"name": "nauman-test",
70-
"tags": {
71-
"hello": "world"
72-
}
56+
"kid": "https://test-vault.vault.azure.net/keys/test-key-2",
57+
"name": "test-key-2"
7358
},
7459
{
7560
"attributes": {
7661
"created": "2022-04-10T17:57:43+00:00",
7762
"enabled": true,
7863
"expires": keyExpiryFail,
7964
"notBefore": null,
80-
"recoveryLevel": "CustomizedRecoverable+Purgeable",
8165
"updated": "2022-04-10T17:57:43+00:00"
8266
},
83-
"kid": "https://nauman-test.vault.azure.net/keys/nauman-test",
84-
"managed": null,
85-
"name": "nauman-test",
86-
"tags": {
87-
"hello": "world"
88-
}
67+
"kid": "https://test-vault.vault.azure.net/keys/test-key-3",
68+
"name": "test-key-3"
8969
},
9070
{
9171
"attributes": {
9272
"created": "2022-04-10T17:57:43+00:00",
9373
"enabled": true,
9474
"expires": keyExpired,
9575
"notBefore": null,
96-
"recoveryLevel": "CustomizedRecoverable+Purgeable",
9776
"updated": "2022-04-10T17:57:43+00:00"
9877
},
99-
"kid": "https://nauman-test.vault.azure.net/keys/nauman-test",
100-
"managed": null,
101-
"name": "nauman-test",
102-
"tags": {
103-
"hello": "world"
104-
}
78+
"kid": "https://test-vault.vault.azure.net/keys/test-key-4",
79+
"name": "test-key-4"
10580
}
10681
];
10782

@@ -116,7 +91,7 @@ const createCache = (err, list, keys) => {
11691
},
11792
getKeys: {
11893
'eastus': {
119-
'/subscriptions/abcdfget-ebf6-437f-a3b0-28fc0d22111e/resourceGroups/akhtar-rg/providers/Microsoft.KeyVault/vaults/nauman-test': {
94+
'/subscriptions/123/resourceGroups/test-rg/providers/Microsoft.KeyVault/vaults/test-vault': {
12095
err: err,
12196
data: keys
12297
}
@@ -126,9 +101,9 @@ const createCache = (err, list, keys) => {
126101
}
127102
};
128103

129-
describe('keyVaultKeyExpiry', function() {
104+
describe('keyVaultKeyExpiryRbac', function() {
130105
describe('run', function() {
131-
it('should give passing result if no keys found', function(done) {
106+
it('should give passing result if no key vaults found', function(done) {
132107
const callback = (err, results) => {
133108
expect(results.length).to.equal(1);
134109
expect(results[0].status).to.equal(0);
@@ -144,7 +119,7 @@ describe('keyVaultKeyExpiry', function() {
144119
const callback = (err, results) => {
145120
expect(results.length).to.equal(1);
146121
expect(results[0].status).to.equal(0);
147-
expect(results[0].message).to.include('Key expiration is not enabled');
122+
expect(results[0].message).to.include('Key expiration is not enabled in RBAC vault');
148123
expect(results[0].region).to.equal('eastus');
149124
done()
150125
};
@@ -156,36 +131,36 @@ describe('keyVaultKeyExpiry', function() {
156131
const callback = (err, results) => {
157132
expect(results.length).to.equal(1);
158133
expect(results[0].status).to.equal(0);
159-
expect(results[0].message).to.include('Key expires in');
134+
expect(results[0].message).to.include('Key in RBAC vault expires in');
160135
expect(results[0].region).to.equal('eastus');
161136
done()
162137
};
163138

164-
auth.run(createCache(null, listKeyVaults, [getKeys[1]]), { key_vault_key_expiry_fail: '30' }, callback);
139+
auth.run(createCache(null, [listKeyVaults[0]], [getKeys[1]]), { key_vault_key_expiry_fail: '30' }, callback);
165140
});
166141

167-
it('should give failing results if the key has reached', function(done) {
142+
it('should give failing results if the key has expired', function(done) {
168143
const callback = (err, results) => {
169144
expect(results.length).to.equal(1);
170145
expect(results[0].status).to.equal(2);
171-
expect(results[0].message).to.include('Key expired');
146+
expect(results[0].message).to.include('Key in RBAC vault expired');
172147
expect(results[0].region).to.equal('eastus');
173148
done()
174149
};
175150

176-
auth.run(createCache(null, listKeyVaults, [getKeys[3]]), { key_vault_key_expiry_fail: '40' }, callback);
151+
auth.run(createCache(null, [listKeyVaults[0]], [getKeys[3]]), { key_vault_key_expiry_fail: '40' }, callback);
177152
});
178153

179-
it('should give failing results if the key expired within failure expiry date', function(done) {
154+
it('should give failing result if the key expires within failure expiry date', function(done) {
180155
const callback = (err, results) => {
181156
expect(results.length).to.equal(1);
182157
expect(results[0].status).to.equal(2);
183-
expect(results[0].message).to.include('Key expires');
158+
expect(results[0].message).to.include('Key in RBAC vault expires');
184159
expect(results[0].region).to.equal('eastus');
185160
done()
186161
};
187162

188-
auth.run(createCache(null, listKeyVaults, [getKeys[2]]), { key_vault_key_expiry_fail: '40' }, callback);
163+
auth.run(createCache(null, [listKeyVaults[0]], [getKeys[2]]), { key_vault_key_expiry_fail: '40' }, callback);
189164
});
190165
});
191-
});
166+
});

0 commit comments

Comments
 (0)