Compare commits
640 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38bc336771 | ||
|
|
276f6f9fb1 | ||
|
|
2386c71c4f | ||
|
|
21c52db66b | ||
|
|
13cfa02f80 | ||
|
|
eedfbe3e7a | ||
|
|
fe03eb4436 | ||
|
|
d8e45d5c3f | ||
|
|
12e9fb5eeb | ||
|
|
957ffaabae | ||
|
|
cb76e5a23c | ||
|
|
b17cc563ff | ||
|
|
06a0b12efb | ||
|
|
d5bd5ebb7d | ||
|
|
0a9a1c26db | ||
|
|
83bfd8a2d4 | ||
|
|
e5d2c0c700 | ||
|
|
590a5669d6 | ||
|
|
e042740f67 | ||
|
|
dab2ecaa6b | ||
|
|
f9f4133b48 | ||
|
|
33dd21897d | ||
|
|
cb2ef23a29 | ||
|
|
e70e01196f | ||
|
|
f70b9e6eb4 | ||
|
|
d186c69473 | ||
|
|
4d817c48a8 | ||
|
|
c13cab792b | ||
|
|
80aa463aa2 | ||
|
|
bd28b17ad9 | ||
|
|
223119e303 | ||
|
|
7c45cb45ae | ||
|
|
ac11c6729b | ||
|
|
1677654dea | ||
|
|
bc5a7a961b | ||
|
|
c10462223d | ||
|
|
54a9f412e8 | ||
|
|
5a107c58bb | ||
|
|
8f091e7548 | ||
|
|
8cdc7b18c7 | ||
|
|
9f2e87e9fb | ||
|
|
e119458048 | ||
|
|
c2983faf1d | ||
|
|
a09855207e | ||
|
|
1e1859ba6f | ||
|
|
a3937e48a8 | ||
|
|
d2aa53a2ec | ||
|
|
b0bdeea60f | ||
|
|
465e64b9ac | ||
|
|
fc53b28997 | ||
|
|
72e701a4b5 | ||
|
|
2298d5356d | ||
|
|
54137be92b | ||
|
|
7ffb12268d | ||
|
|
790fff460a | ||
|
|
9055dbafe3 | ||
|
|
4454d9115e | ||
|
|
0d74dec446 | ||
|
|
0313dba7b4 | ||
|
|
3fafac75ef | ||
|
|
6b24b46f3d | ||
|
|
474e39a4c9 | ||
|
|
e652298b6a | ||
|
|
9340ae43f3 | ||
|
|
552024c53e | ||
|
|
3aba71ad2f | ||
|
|
ade511df28 | ||
|
|
fc650214d4 | ||
|
|
8266fd0c6f | ||
|
|
f4308032c3 | ||
|
|
1e1f445ade | ||
|
|
d41b0332ac | ||
|
|
7258466572 | ||
|
|
76db92ea14 | ||
|
|
ad3cd66e08 | ||
|
|
22f8855ad7 | ||
|
|
36e095c830 | ||
|
|
887cac1264 | ||
|
|
13059e0568 | ||
|
|
9e8023d716 | ||
|
|
c54ba5fd8c | ||
|
|
db80e063d4 | ||
|
|
b6aa12706a | ||
|
|
c1caf6717d | ||
|
|
513fd9f532 | ||
|
|
bf77f817cb | ||
|
|
e0bfef2ece | ||
|
|
4a87f908a8 | ||
|
|
16d95e5155 | ||
|
|
1797b54259 | ||
|
|
f289c8fb2e | ||
|
|
e4ad881a69 | ||
|
|
138bca38e7 | ||
|
|
44f7af3580 | ||
|
|
2d832bca15 | ||
|
|
efa75a62e3 | ||
|
|
5763bca317 | ||
|
|
c335334402 | ||
|
|
5bf3f70717 | ||
|
|
92c8a440ea | ||
|
|
b92d8a014c | ||
|
|
aced44f051 | ||
|
|
49c9d2b077 | ||
|
|
61beacf085 | ||
|
|
02f432238e | ||
|
|
864d178e01 | ||
|
|
78f0b823a9 | ||
|
|
26cdc7a0ee | ||
|
|
5e773f1eee | ||
|
|
4a7ac7df22 | ||
|
|
5250670d5d | ||
|
|
de4a825db8 | ||
|
|
c256419144 | ||
|
|
7bdca0420e | ||
|
|
3aa1fbced9 | ||
|
|
dbbb70027a | ||
|
|
b4e78d28f8 | ||
|
|
e3d4e38a59 | ||
|
|
386f558eae | ||
|
|
e08424d3a3 | ||
|
|
03ad403e7a | ||
|
|
4a674aae99 | ||
|
|
8ee3744027 | ||
|
|
965327e801 | ||
|
|
f82ea43324 | ||
|
|
a5c63845b4 | ||
|
|
034faa72cf | ||
|
|
9bcd617964 | ||
|
|
0db975dc7b | ||
|
|
a51fa7703b | ||
|
|
69fad0009d | ||
|
|
e721251936 | ||
|
|
2fe767e3e5 | ||
|
|
6328ef4444 | ||
|
|
50b8e084e7 | ||
|
|
3d88544feb | ||
|
|
62e602c32e | ||
|
|
47a82560ea | ||
|
|
f7bbcc98b3 | ||
|
|
98a587aa15 | ||
|
|
d2e34c42fd | ||
|
|
605b07901e | ||
|
|
18f02fac68 | ||
|
|
28ea37f367 | ||
|
|
65a737bb58 | ||
|
|
7423cd2f93 | ||
|
|
babd026351 | ||
|
|
dd6e5a9029 | ||
|
|
02519a4429 | ||
|
|
6575121b7a | ||
|
|
5b66368f0d | ||
|
|
971c6720e4 | ||
|
|
3afccc279f | ||
|
|
8f015d0672 | ||
|
|
f33b96861c | ||
|
|
9832ce2ff9 | ||
|
|
490cbbaa48 | ||
|
|
d1c91093e2 | ||
|
|
66fe101ccd | ||
|
|
7ab8c6b154 | ||
|
|
73017b14c3 | ||
|
|
f55495cd6a | ||
|
|
e97146b5a3 | ||
|
|
58f056c76d | ||
|
|
338bbc7a1f | ||
|
|
4ba54738a9 | ||
|
|
235fd2adc4 | ||
|
|
b15d518c94 | ||
|
|
021e1c122c | ||
|
|
014b0dd6f6 | ||
|
|
f9f68f9b86 | ||
|
|
11a8ba131a | ||
|
|
858de64f8e | ||
|
|
676e60afb7 | ||
|
|
b1968f3f8b | ||
|
|
d2d077afaa | ||
|
|
7097ca401d | ||
|
|
73e9a1eb9e | ||
|
|
0439d455fb | ||
|
|
d57f665a78 | ||
|
|
859c731a13 | ||
|
|
2e7613ddec | ||
|
|
57e9436783 | ||
|
|
2f153fda2e | ||
|
|
cbcb5905a3 | ||
|
|
6a2fb37615 | ||
|
|
6403feaff9 | ||
|
|
47736910ca | ||
|
|
ead592a0bf | ||
|
|
d5bdba9244 | ||
|
|
4f033cec8d | ||
|
|
a58f4b2498 | ||
|
|
01522ed8c7 | ||
|
|
fa99ee9d5b | ||
|
|
6efe634850 | ||
|
|
60a1497eaf | ||
|
|
1d0cbc08df | ||
|
|
4d4280033b | ||
|
|
fd58775cae | ||
|
|
ccb0e93da2 | ||
|
|
c2a05da908 | ||
|
|
e1da9e60fc | ||
|
|
d044e535e0 | ||
|
|
293560dcd4 | ||
|
|
90ebb815d5 | ||
|
|
3d3d418ee6 | ||
|
|
f875cd05be | ||
|
|
435911489f | ||
|
|
5fcfcd53aa | ||
|
|
bc09215aad | ||
|
|
5f7e109e3d | ||
|
|
b75a5050d7 | ||
|
|
be497f7083 | ||
|
|
0ccae3e15b | ||
|
|
d736c32aec | ||
|
|
8ea5ba5d3f | ||
|
|
60c341befd | ||
|
|
be4f58ed8f | ||
|
|
d82d1abab6 | ||
|
|
0d81bd457c | ||
|
|
af2b19436f | ||
|
|
51beb3c7e4 | ||
|
|
5061456735 | ||
|
|
b01eb3af95 | ||
|
|
328bebc168 | ||
|
|
fc63fffa15 | ||
|
|
707584b2ef | ||
|
|
561459d93b | ||
|
|
25e48ae546 | ||
|
|
513bb3e8d0 | ||
|
|
04710ca908 | ||
|
|
fcf0fcf20c | ||
|
|
2ff40d8e37 | ||
|
|
1bab5b06a4 | ||
|
|
01cd4bcb47 | ||
|
|
49b2a559ae | ||
|
|
9212d24685 | ||
|
|
eb43b11202 | ||
|
|
5c4cae8c9d | ||
|
|
cfd7099743 | ||
|
|
19ae237d29 | ||
|
|
9cda78e561 | ||
|
|
cc31872a7f | ||
|
|
3c2c896708 | ||
|
|
b73da9c54c | ||
|
|
414a45bfb0 | ||
|
|
2a6f808bca | ||
|
|
cdf2a13bbd | ||
|
|
3e3e8a14ee | ||
|
|
37e180827a | ||
|
|
b047b54545 | ||
|
|
b7bb4bbd57 | ||
|
|
86cf2cd233 | ||
|
|
ab12c201b4 | ||
|
|
a8f03d859c | ||
|
|
3c7580f024 | ||
|
|
277833e388 | ||
|
|
eb16d7e6f9 | ||
|
|
1418068d2b | ||
|
|
774346f5f8 | ||
|
|
1aab88e6ca | ||
|
|
613f49b8bb | ||
|
|
5c95dc6e20 | ||
|
|
cbc2713bee | ||
|
|
2955975793 | ||
|
|
f8299d7f40 | ||
|
|
e855d44523 | ||
|
|
64e7715480 | ||
|
|
2e9a74f609 | ||
|
|
11a1230738 | ||
|
|
298373742e | ||
|
|
dc7aeecd85 | ||
|
|
15a7de7b24 | ||
|
|
714d0d4092 | ||
|
|
225d7f39d1 | ||
|
|
0005798c83 | ||
|
|
1d9078f9be | ||
|
|
510ac7005a | ||
|
|
c049b968a5 | ||
|
|
858698f7cd | ||
|
|
d104f6f8fc | ||
|
|
3ecf0d3230 | ||
|
|
6e4131fee4 | ||
|
|
41fa6bc8ed | ||
|
|
58a29bf058 | ||
|
|
7dac17de18 | ||
|
|
799d7de182 | ||
|
|
735af02f59 | ||
|
|
ad3f3799fa | ||
|
|
5f97df015e | ||
|
|
ff18fd2c38 | ||
|
|
3ab0cd02df | ||
|
|
c31072f42f | ||
|
|
c01c59023a | ||
|
|
4329aac377 | ||
|
|
c10b31e9d0 | ||
|
|
71a789c0b4 | ||
|
|
deb9847e2b | ||
|
|
9e9e7e1e96 | ||
|
|
d34e0341e2 | ||
|
|
aec254b05a | ||
|
|
f8b420047a | ||
|
|
7e6e4c0bc6 | ||
|
|
71fb59943c | ||
|
|
34419d0ca1 | ||
|
|
475a36f0d7 | ||
|
|
1234c1e7e2 | ||
|
|
a4a400facf | ||
|
|
ed2ca4d896 | ||
|
|
ce42e4d1cd | ||
|
|
b048128e77 | ||
|
|
635c257502 | ||
|
|
58a38c08d7 | ||
|
|
8fbee7737b | ||
|
|
e84f5f184e | ||
|
|
0bd26b19d7 | ||
|
|
64f82d5d51 | ||
|
|
f63ff994ce | ||
|
|
a10ee43271 | ||
|
|
54ed29e08d | ||
|
|
cc097e7a3f | ||
|
|
5de92ada43 | ||
|
|
0c546211cf | ||
|
|
4dc5a3a67c | ||
|
|
c51b226ceb | ||
|
|
0a5ca6cf74 | ||
|
|
96957219e4 | ||
|
|
32b7620db3 | ||
|
|
347f65e089 | ||
|
|
16628a427e | ||
|
|
ed16034a25 | ||
|
|
0c5f144e41 | ||
|
|
acc7d6e7dc | ||
|
|
84b4139052 | ||
|
|
9943643958 | ||
|
|
9ceaefb663 | ||
|
|
ec03ea5bc1 | ||
|
|
5855633c1f | ||
|
|
a53bc2bc2e | ||
|
|
88445820ed | ||
|
|
044ed3ae98 | ||
|
|
6f48012234 | ||
|
|
d344318dd4 | ||
|
|
6273dd3d83 | ||
|
|
0f3f3cbffd | ||
|
|
3244123b21 | ||
|
|
cba2ee3622 | ||
|
|
25ed925df5 | ||
|
|
8c5bd60bab | ||
|
|
c5510556a7 | ||
|
|
bbcfca84ef | ||
|
|
1260e94c2a | ||
|
|
8a02574303 | ||
|
|
c930f08348 | ||
|
|
5204acb5d0 | ||
|
|
784aaa98c9 | ||
|
|
745e2494bc | ||
|
|
c00792519d | ||
|
|
142fe5a12c | ||
|
|
5b127f232e | ||
|
|
c22bf01003 | ||
|
|
05e4911d6f | ||
|
|
9b551ef0ba | ||
|
|
56a8bb2349 | ||
|
|
8503c6a64d | ||
|
|
820f18da4d | ||
|
|
51a2432ebf | ||
|
|
6639534e97 | ||
|
|
0621577c7d | ||
|
|
26a507e3db | ||
|
|
244b540fe0 | ||
|
|
030ca4c173 | ||
|
|
88a2810f29 | ||
|
|
9164ee363a | ||
|
|
4cd47fdcc5 | ||
|
|
708852a3cb | ||
|
|
4a93bdf3ea | ||
|
|
22e7d2a811 | ||
|
|
93eca1dff2 | ||
|
|
9afe7408cd | ||
|
|
5dc2347a25 | ||
|
|
e3a0124b10 | ||
|
|
16af89c281 | ||
|
|
621e4258c8 | ||
|
|
ac6272e739 | ||
|
|
6e84f517a9 | ||
|
|
fdbdb3ad86 | ||
|
|
7adcf5ca46 | ||
|
|
fe6716cf76 | ||
|
|
3c2096db68 | ||
|
|
58cad1a6b3 | ||
|
|
662e67ff16 | ||
|
|
8d577b872f | ||
|
|
b55290f3cb | ||
|
|
e8d3eb7393 | ||
|
|
47fa16e35f | ||
|
|
a87f769b85 | ||
|
|
8e63fa4594 | ||
|
|
63501a0d59 | ||
|
|
828fb37ca8 | ||
|
|
40f513d3b6 | ||
|
|
f0b8b66a75 | ||
|
|
d51cdc068b | ||
|
|
f8b382e480 | ||
|
|
1995f43b67 | ||
|
|
69e0392a8b | ||
|
|
1f6319442e | ||
|
|
559c4c0c2c | ||
|
|
feeb5b58d9 | ||
|
|
7a00f79a56 | ||
|
|
10d744704a | ||
|
|
eee35f9cc3 | ||
|
|
b3656761eb | ||
|
|
7b5fe34316 | ||
|
|
4536780a19 | ||
|
|
05d866e6b3 | ||
|
|
0d138cf473 | ||
|
|
dbe539ac80 | ||
|
|
665a39d179 | ||
|
|
5fd5d8c8c5 | ||
|
|
2832b4564c | ||
|
|
d4369a64ee | ||
|
|
81fa1630b7 | ||
|
|
a1c4b35205 | ||
|
|
5e567f3e37 | ||
|
|
c4757684c1 | ||
|
|
a55a6bf94b | ||
|
|
fa1792eb77 | ||
|
|
93a8f6e759 | ||
|
|
4a614855d4 | ||
|
|
8bdd47f912 | ||
|
|
f9e82abadc | ||
|
|
428fda81e2 | ||
|
|
29c9ad602d | ||
|
|
44458e2a97 | ||
|
|
861fb1f54b | ||
|
|
02534f4d55 | ||
|
|
5532cb95a2 | ||
|
|
9176e43fc9 | ||
|
|
cb190f54fc | ||
|
|
4be2539bc2 | ||
|
|
291e2adffa | ||
|
|
fa2ec63f45 | ||
|
|
946c943457 | ||
|
|
0e50766d6e | ||
|
|
58a1610ae0 | ||
|
|
06dc21168a | ||
|
|
305b67fbed | ||
|
|
4da6d152c3 | ||
|
|
25630f1ef5 | ||
|
|
9b01e3f1c9 | ||
|
|
99450400eb | ||
|
|
2f8a8988d7 | ||
|
|
9104d2e89e | ||
|
|
e75022763c | ||
|
|
f0f3fb337d | ||
|
|
f7f01a34c2 | ||
|
|
f9f9ff0cb8 | ||
|
|
522ba05ba8 | ||
|
|
f4f4093466 | ||
|
|
2e16ab0c2c | ||
|
|
6f02606fb7 | ||
|
|
df40142b51 | ||
|
|
cc290d488b | ||
|
|
64328218fc | ||
|
|
8d1356a085 | ||
|
|
4f39dd0f73 | ||
|
|
54ffc8ae45 | ||
|
|
78ab1944bd | ||
|
|
434cf94657 | ||
|
|
dcb893e230 | ||
|
|
ce4fadc378 | ||
|
|
5683d1b1bd | ||
|
|
0eb88d0c10 | ||
|
|
eb1367e54d | ||
|
|
33a4786206 | ||
|
|
8c6606ad95 | ||
|
|
cde9519a76 | ||
|
|
7b2e0d79cb | ||
|
|
5b0da8e92a | ||
|
|
0126d2f77c | ||
|
|
0b436014c9 | ||
|
|
2cb7f223ed | ||
|
|
eca551ed98 | ||
|
|
608fd92861 | ||
|
|
e37d8fe45f | ||
|
|
4cce91ec97 | ||
|
|
72fdde35dc | ||
|
|
d425187778 | ||
|
|
e419aa1f1a | ||
|
|
5506547f7f | ||
|
|
568ed72b3e | ||
|
|
e8cc0e6684 | ||
|
|
4331f69395 | ||
|
|
7cc67ae7cb | ||
|
|
244b3438fc | ||
|
|
1a741f7ca0 | ||
|
|
1447800e2b | ||
|
|
f968fe7512 | ||
|
|
0a2349fad7 | ||
|
|
941b8cbc1e | ||
|
|
3b7b16acfd | ||
|
|
fbc7bb68fc | ||
|
|
0d16880596 | ||
|
|
3b5218128f | ||
|
|
cb731bf1db | ||
|
|
7c4d6eb02d | ||
|
|
c14e7fb17a | ||
|
|
fe57811bc5 | ||
|
|
e073b48f7d | ||
|
|
a9df609593 | ||
|
|
6c3db9646e | ||
|
|
ff9c4c717e | ||
|
|
182374b46f | ||
|
|
0871cda526 | ||
|
|
1b47cba37a | ||
|
|
e5bef36905 | ||
|
|
706d723703 | ||
|
|
51eacbfac5 | ||
|
|
5c2a411982 | ||
|
|
08d65cbc41 | ||
|
|
9d2bf429c1 | ||
|
|
d34f863bd4 | ||
|
|
b4abf1c2c7 | ||
|
|
68baaf589e | ||
|
|
be74e41d84 | ||
|
|
848122b0ec | ||
|
|
0edcb7c0d9 | ||
|
|
cc58e06b5e | ||
|
|
0d6ca606ea | ||
|
|
75ee93789f | ||
|
|
05daddafbf | ||
|
|
7bbce6725d | ||
|
|
789b211586 | ||
|
|
826a043748 | ||
|
|
6761048298 | ||
|
|
738fc9acad | ||
|
|
43c0540de7 | ||
|
|
2d1c3d8121 | ||
|
|
f48a5c650d | ||
|
|
66c18eddb8 | ||
|
|
fdd2ee6365 | ||
|
|
c207f60ad8 | ||
|
|
0eaa95c8c0 | ||
|
|
df2fca5935 | ||
|
|
dcaf5d9c7d | ||
|
|
0112969a97 | ||
|
|
3ec0f3d69c | ||
|
|
5555d300a1 | ||
|
|
8155ef4b60 | ||
|
|
a12402f6c8 | ||
|
|
cf28b814cb | ||
|
|
b05f67db19 | ||
|
|
260f4659d5 | ||
|
|
9e700f298c | ||
|
|
56510734c4 | ||
|
|
3938a4d14e | ||
|
|
fa3b9eeeaf | ||
|
|
eb9d6fa25c | ||
|
|
b53307c1c2 | ||
|
|
c3fc708a66 | ||
|
|
b34ffbe6d0 | ||
|
|
f364315e48 | ||
|
|
3ddb5a13a5 | ||
|
|
a24cc399a4 | ||
|
|
305f4b2688 | ||
|
|
9823171d65 | ||
|
|
4761bd8fda | ||
|
|
9c22698723 | ||
|
|
e3892bbcc6 | ||
|
|
629b156f52 | ||
|
|
c45dd47d34 | ||
|
|
ef8831f784 | ||
|
|
c5a42cf5de | ||
|
|
90ebbfc20f | ||
|
|
17cd0dc91d | ||
|
|
fa1f42af59 | ||
|
|
f45ea1ab53 | ||
|
|
0dde3fe483 | ||
|
|
277dc7dd09 | ||
|
|
3215d0b856 | ||
|
|
0167d5efcd | ||
|
|
b48ac808a6 | ||
|
|
616524775c | ||
|
|
5832849b11 | ||
|
|
467c5d01e9 | ||
|
|
24711a2f39 | ||
|
|
24e8286f35 | ||
|
|
e8a1378ad0 | ||
|
|
76bb418ea9 | ||
|
|
cd8770a3e3 | ||
|
|
da834c0935 | ||
|
|
024ffb1117 | ||
|
|
eed7ab9793 | ||
|
|
032feb343f | ||
|
|
eabccba3fa | ||
|
|
d86d656316 | ||
|
|
fa73c91b0b | ||
|
|
2eee50832d | ||
|
|
b40736918b | ||
|
|
ffb1a2e30f | ||
|
|
d6c3c0c6c1 | ||
|
|
ee251721ac | ||
|
|
fdbb9195d5 | ||
|
|
c68b08d9af | ||
|
|
3653bbfca0 | ||
|
|
05c7cc7277 | ||
|
|
5670bf099b | ||
|
|
0c324b0f09 | ||
|
|
968557e38e | ||
|
|
882cdebacb | ||
|
|
07753e1774 | ||
|
|
5b984507fc | ||
|
|
27df481967 | ||
|
|
0943031f23 | ||
|
|
2d95168de0 | ||
|
|
97cae8f92c | ||
|
|
eb213bac92 | ||
|
|
8187788b2c | ||
|
|
c80e08abce | ||
|
|
42fd851e5c | ||
|
|
70e4ebccab | ||
|
|
140f87c741 | ||
|
|
b0d756123e | ||
|
|
6188c92916 | ||
|
|
34c6f96728 | ||
|
|
50fd047c0b | ||
|
|
5bcc05b536 | ||
|
|
ce7d6c8dd5 | ||
|
|
d87a1e28b4 | ||
|
|
227306c572 | ||
|
|
45c2691f89 | ||
|
|
d0c81245b8 | ||
|
|
e494afb1aa | ||
|
|
ecc3c1cf3b | ||
|
|
228b16416a | ||
|
|
17eb74842a | ||
|
|
c01ff74c73 | ||
|
|
f88613b26d | ||
|
|
3464f4241f |
2
.github/CODEOWNERS
vendored
@@ -1 +1 @@
|
||||
* @prowler-cloud/prowler-team
|
||||
* @prowler-cloud/prowler-oss
|
||||
|
||||
52
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,52 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: "[Bug]: "
|
||||
labels: bug, status/needs-triage
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
Please use this template to create your bug report. By providing as much info as possible you help us understand the issue, reproduce it and resolve it for you quicker. Therefore, take a couple of extra minutes to make sure you have provided all info needed.
|
||||
|
||||
PROTIP: record your screen and attach it as a gif to showcase the issue.
|
||||
|
||||
- How to record and attach gif: https://bit.ly/2Mi8T6K
|
||||
-->
|
||||
|
||||
**What happened?**
|
||||
A clear and concise description of what the bug is or what is not working as expected
|
||||
|
||||
|
||||
**How to reproduce it**
|
||||
Steps to reproduce the behavior:
|
||||
1. What command are you running?
|
||||
2. Cloud provider you are launching
|
||||
3. Environment you have like single account, multi-account, organizations, multi or single subsctiption, etc.
|
||||
4. See error
|
||||
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
|
||||
**Screenshots or Logs**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
Also, you can add logs (anonymize them first!). Here a command that may help to share a log
|
||||
`prowler <your arguments> --log-level DEBUG --log-file $(date +%F)_debug.log` then attach here the log file.
|
||||
|
||||
|
||||
**From where are you running Prowler?**
|
||||
Please, complete the following information:
|
||||
- Resource: (e.g. EC2 instance, Fargate task, Docker container manually, EKS, Cloud9, CodeBuild, workstation, etc.)
|
||||
- OS: [e.g. Amazon Linux 2, Mac, Alpine, Windows, etc. ]
|
||||
- Prowler Version [`prowler --version`]:
|
||||
- Python version [`python --version`]:
|
||||
- Pip version [`pip --version`]:
|
||||
- Installation method (Are you running it from pip package or cloning the github repo?):
|
||||
- Others:
|
||||
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
97
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
name: 🐞 Bug Report
|
||||
description: Create a report to help us improve
|
||||
title: "[Bug]: "
|
||||
labels: ["bug", "status/needs-triage"]
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
id: reproduce
|
||||
attributes:
|
||||
label: Steps to Reproduce
|
||||
description: Steps to reproduce the behavior
|
||||
placeholder: |-
|
||||
1. What command are you running?
|
||||
2. Cloud provider you are launching
|
||||
3. Environment you have, like single account, multi-account, organizations, multi or single subscription, etc.
|
||||
4. See error
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: A clear and concise description of what you expected to happen.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: actual
|
||||
attributes:
|
||||
label: Actual Result with Screenshots or Logs
|
||||
description: If applicable, add screenshots to help explain your problem. Also, you can add logs (anonymize them first!). Here a command that may help to share a log `prowler <your arguments> --log-level DEBUG --log-file $(date +%F)_debug.log` then attach here the log file.
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: type
|
||||
attributes:
|
||||
label: How did you install Prowler?
|
||||
options:
|
||||
- Cloning the repository from github.com (git clone)
|
||||
- From pip package (pip install prowler)
|
||||
- From brew (brew install prowler)
|
||||
- Docker (docker pull toniblyx/prowler)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment Resource
|
||||
description: From where are you running Prowler?
|
||||
placeholder: |-
|
||||
1. EC2 instance
|
||||
2. Fargate task
|
||||
3. Docker container locally
|
||||
4. EKS
|
||||
5. Cloud9
|
||||
6. CodeBuild
|
||||
7. Workstation
|
||||
8. Other(please specify)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: os
|
||||
attributes:
|
||||
label: OS used
|
||||
description: Which OS are you using?
|
||||
placeholder: |-
|
||||
1. Amazon Linux 2
|
||||
2. MacOS
|
||||
3. Alpine Linux
|
||||
4. Windows
|
||||
5. Other(please specify)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: prowler-version
|
||||
attributes:
|
||||
label: Prowler version
|
||||
description: Which Prowler version are you using?
|
||||
placeholder: |-
|
||||
prowler --version
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: pip-version
|
||||
attributes:
|
||||
label: Pip version
|
||||
description: Which pip version are you using?
|
||||
placeholder: |-
|
||||
pip --version
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
description: Additional context
|
||||
label: Context
|
||||
validations:
|
||||
required: false
|
||||
36
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: 💡 Feature Request
|
||||
description: Suggest an idea for this project
|
||||
labels: ["enhancement", "status/needs-triage"]
|
||||
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
id: Problem
|
||||
attributes:
|
||||
label: New feature motivation
|
||||
description: Is your feature request related to a problem? Please describe
|
||||
placeholder: |-
|
||||
1. A clear and concise description of what the problem is. Ex. I'm always frustrated when
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: Solution
|
||||
attributes:
|
||||
label: Solution Proposed
|
||||
description: A clear and concise description of what you want to happen.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: Alternatives
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: Context
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context or screenshots about the feature request here.
|
||||
validations:
|
||||
required: false
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement, status/needs-triage
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
2
.github/dependabot.yml
vendored
@@ -8,7 +8,7 @@ updates:
|
||||
- package-ecosystem: "pip" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "daily"
|
||||
interval: "weekly"
|
||||
target-branch: master
|
||||
labels:
|
||||
- "dependencies"
|
||||
|
||||
170
.github/workflows/build-lint-push-containers.yml
vendored
@@ -15,36 +15,17 @@ on:
|
||||
env:
|
||||
AWS_REGION_STG: eu-west-1
|
||||
AWS_REGION_PLATFORM: eu-west-1
|
||||
AWS_REGION_PRO: us-east-1
|
||||
AWS_REGION: us-east-1
|
||||
IMAGE_NAME: prowler
|
||||
LATEST_TAG: latest
|
||||
STABLE_TAG: stable
|
||||
TEMPORARY_TAG: temporary
|
||||
DOCKERFILE_PATH: ./Dockerfile
|
||||
PYTHON_VERSION: 3.9
|
||||
|
||||
jobs:
|
||||
# Lint Dockerfile using Hadolint
|
||||
# dockerfile-linter:
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# -
|
||||
# name: Checkout
|
||||
# uses: actions/checkout@v3
|
||||
# -
|
||||
# name: Install Hadolint
|
||||
# run: |
|
||||
# VERSION=$(curl --silent "https://api.github.com/repos/hadolint/hadolint/releases/latest" | \
|
||||
# grep '"tag_name":' | \
|
||||
# sed -E 's/.*"v([^"]+)".*/\1/' \
|
||||
# ) && curl -L -o /tmp/hadolint https://github.com/hadolint/hadolint/releases/download/v${VERSION}/hadolint-Linux-x86_64 \
|
||||
# && chmod +x /tmp/hadolint
|
||||
# -
|
||||
# name: Run Hadolint
|
||||
# run: |
|
||||
# /tmp/hadolint util/Dockerfile
|
||||
|
||||
# Build Prowler OSS container
|
||||
container-build:
|
||||
container-build-push:
|
||||
# needs: dockerfile-linter
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
@@ -52,87 +33,30 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: setup python (release)
|
||||
|
||||
- name: Setup python (release)
|
||||
if: github.event_name == 'release'
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9 #install the python needed
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
|
||||
- name: Install dependencies (release)
|
||||
if: github.event_name == 'release'
|
||||
run: |
|
||||
pipx install poetry
|
||||
pipx inject poetry poetry-bumpversion
|
||||
|
||||
- name: Update Prowler version (release)
|
||||
if: github.event_name == 'release'
|
||||
run: |
|
||||
poetry version ${{ github.event.release.tag_name }}
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
# Without pushing to registries
|
||||
push: false
|
||||
tags: ${{ env.IMAGE_NAME }}:${{ env.TEMPORARY_TAG }}
|
||||
file: ${{ env.DOCKERFILE_PATH }}
|
||||
outputs: type=docker,dest=/tmp/${{ env.IMAGE_NAME }}.tar
|
||||
- name: Share image between jobs
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ env.IMAGE_NAME }}.tar
|
||||
path: /tmp/${{ env.IMAGE_NAME }}.tar
|
||||
|
||||
# Lint Prowler OSS container using Dockle
|
||||
# container-linter:
|
||||
# needs: container-build
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# -
|
||||
# name: Get container image from shared
|
||||
# uses: actions/download-artifact@v2
|
||||
# with:
|
||||
# name: ${{ env.IMAGE_NAME }}.tar
|
||||
# path: /tmp
|
||||
# -
|
||||
# name: Load Docker image
|
||||
# run: |
|
||||
# docker load --input /tmp/${{ env.IMAGE_NAME }}.tar
|
||||
# docker image ls -a
|
||||
# -
|
||||
# name: Install Dockle
|
||||
# run: |
|
||||
# VERSION=$(curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \
|
||||
# grep '"tag_name":' | \
|
||||
# sed -E 's/.*"v([^"]+)".*/\1/' \
|
||||
# ) && curl -L -o dockle.deb https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.deb \
|
||||
# && sudo dpkg -i dockle.deb && rm dockle.deb
|
||||
# -
|
||||
# name: Run Dockle
|
||||
# run: dockle ${{ env.IMAGE_NAME }}:${{ env.TEMPORARY_TAG }}
|
||||
|
||||
# Push Prowler OSS container to registries
|
||||
container-push:
|
||||
# needs: container-linter
|
||||
needs: container-build
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read # This is required for actions/checkout
|
||||
steps:
|
||||
- name: Get container image from shared
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: ${{ env.IMAGE_NAME }}.tar
|
||||
path: /tmp
|
||||
- name: Load Docker image
|
||||
run: |
|
||||
docker load --input /tmp/${{ env.IMAGE_NAME }}.tar
|
||||
docker image ls -a
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Login to Public ECR
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
@@ -140,55 +64,53 @@ jobs:
|
||||
username: ${{ secrets.PUBLIC_ECR_AWS_ACCESS_KEY_ID }}
|
||||
password: ${{ secrets.PUBLIC_ECR_AWS_SECRET_ACCESS_KEY }}
|
||||
env:
|
||||
AWS_REGION: ${{ env.AWS_REGION_PRO }}
|
||||
AWS_REGION: ${{ env.AWS_REGION }}
|
||||
|
||||
- name: Tag (latest)
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Build and push container image (latest)
|
||||
if: github.event_name == 'push'
|
||||
run: |
|
||||
docker tag ${{ env.IMAGE_NAME }}:${{ env.TEMPORARY_TAG }} ${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.LATEST_TAG }}
|
||||
docker tag ${{ env.IMAGE_NAME }}:${{ env.TEMPORARY_TAG }} ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.LATEST_TAG }}
|
||||
|
||||
- # Push to master branch - push "latest" tag
|
||||
name: Push (latest)
|
||||
if: github.event_name == 'push'
|
||||
run: |
|
||||
docker push ${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.LATEST_TAG }}
|
||||
docker push ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.LATEST_TAG }}
|
||||
|
||||
- # Tag the new release (stable and release tag)
|
||||
name: Tag (release)
|
||||
if: github.event_name == 'release'
|
||||
run: |
|
||||
docker tag ${{ env.IMAGE_NAME }}:${{ env.TEMPORARY_TAG }} ${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }}
|
||||
docker tag ${{ env.IMAGE_NAME }}:${{ env.TEMPORARY_TAG }} ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }}
|
||||
|
||||
docker tag ${{ env.IMAGE_NAME }}:${{ env.TEMPORARY_TAG }} ${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.STABLE_TAG }}
|
||||
docker tag ${{ env.IMAGE_NAME }}:${{ env.TEMPORARY_TAG }} ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.STABLE_TAG }}
|
||||
|
||||
- # Push the new release (stable and release tag)
|
||||
name: Push (release)
|
||||
if: github.event_name == 'release'
|
||||
run: |
|
||||
docker push ${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }}
|
||||
docker push ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }}
|
||||
|
||||
docker push ${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.STABLE_TAG }}
|
||||
docker push ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.STABLE_TAG }}
|
||||
|
||||
- name: Delete artifacts
|
||||
if: always()
|
||||
uses: geekyeggo/delete-artifact@v1
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
name: ${{ env.IMAGE_NAME }}.tar
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.LATEST_TAG }}
|
||||
${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.LATEST_TAG }}
|
||||
file: ${{ env.DOCKERFILE_PATH }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- name: Build and push container image (release)
|
||||
if: github.event_name == 'release'
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
# Use local context to get changes
|
||||
# https://github.com/docker/build-push-action#path-context
|
||||
context: .
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }}
|
||||
${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.STABLE_TAG }}
|
||||
${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }}
|
||||
${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.STABLE_TAG }}
|
||||
file: ${{ env.DOCKERFILE_PATH }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
dispatch-action:
|
||||
needs: container-push
|
||||
needs: container-build-push
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get latest commit info
|
||||
if: github.event_name == 'push'
|
||||
run: |
|
||||
LATEST_COMMIT_HASH=$(echo ${{ github.event.after }} | cut -b -7)
|
||||
echo "LATEST_COMMIT_HASH=${LATEST_COMMIT_HASH}" >> $GITHUB_ENV
|
||||
- name: Dispatch event for latest
|
||||
if: github.event_name == 'push'
|
||||
run: |
|
||||
curl https://api.github.com/repos/${{ secrets.DISPATCH_OWNER }}/${{ secrets.DISPATCH_REPO }}/dispatches -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{ secrets.ACCESS_TOKEN }}" -H "X-GitHub-Api-Version: 2022-11-28" --data '{"event_type":"dispatch","client_payload":{"version":"latest"}'
|
||||
curl https://api.github.com/repos/${{ secrets.DISPATCH_OWNER }}/${{ secrets.DISPATCH_REPO }}/dispatches -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{ secrets.ACCESS_TOKEN }}" -H "X-GitHub-Api-Version: 2022-11-28" --data '{"event_type":"dispatch","client_payload":{"version":"latest", "tag": "${{ env.LATEST_COMMIT_HASH }}"}}'
|
||||
- name: Dispatch event for release
|
||||
if: github.event_name == 'release'
|
||||
run: |
|
||||
|
||||
18
.github/workflows/pull-request.yml
vendored
@@ -13,18 +13,21 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.9"]
|
||||
python-version: ["3.9", "3.10", "3.11"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install poetry
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pipx install poetry
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: "poetry"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install poetry
|
||||
poetry install
|
||||
poetry run pip list
|
||||
VERSION=$(curl --silent "https://api.github.com/repos/hadolint/hadolint/releases/latest" | \
|
||||
@@ -32,6 +35,9 @@ jobs:
|
||||
sed -E 's/.*"v([^"]+)".*/\1/' \
|
||||
) && curl -L -o /tmp/hadolint "https://github.com/hadolint/hadolint/releases/download/v${VERSION}/hadolint-Linux-x86_64" \
|
||||
&& chmod +x /tmp/hadolint
|
||||
- name: Poetry check
|
||||
run: |
|
||||
poetry lock --check
|
||||
- name: Lint with flake8
|
||||
run: |
|
||||
poetry run flake8 . --ignore=E266,W503,E203,E501,W605,E128 --exclude contrib
|
||||
@@ -55,4 +61,8 @@ jobs:
|
||||
/tmp/hadolint Dockerfile --ignore=DL3013
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
poetry run pytest tests -n auto
|
||||
poetry run pytest -n auto --cov=./prowler --cov-report=xml tests
|
||||
- name: Upload coverage reports to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
38
.github/workflows/pypi-release.yml
vendored
@@ -19,14 +19,15 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ env.GITHUB_BRANCH }}
|
||||
- name: setup python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9 #install the python needed
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pipx install poetry
|
||||
pipx inject poetry poetry-bumpversion
|
||||
- name: setup python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.9
|
||||
cache: 'poetry'
|
||||
- name: Change version and Build package
|
||||
run: |
|
||||
poetry version ${{ env.RELEASE_TAG }}
|
||||
@@ -41,20 +42,11 @@ jobs:
|
||||
run: |
|
||||
poetry config pypi-token.pypi ${{ secrets.PYPI_API_TOKEN }}
|
||||
poetry publish
|
||||
- name: Replicate PyPi Package
|
||||
run: |
|
||||
rm -rf ./dist && rm -rf ./build && rm -rf prowler.egg-info
|
||||
python util/replicate_pypi_package.py
|
||||
poetry build
|
||||
- name: Publish prowler-cloud package to PyPI
|
||||
run: |
|
||||
poetry config pypi-token.pypi ${{ secrets.PYPI_API_TOKEN }}
|
||||
poetry publish
|
||||
# Create pull request with new version
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
token: ${{ secrets.PROWLER_ACCESS_TOKEN }}
|
||||
commit-message: "chore(release): update Prowler Version to ${{ env.RELEASE_TAG }}."
|
||||
branch: release-${{ env.RELEASE_TAG }}
|
||||
labels: "status/waiting-for-revision, severity/low"
|
||||
@@ -67,3 +59,21 @@ jobs:
|
||||
### License
|
||||
|
||||
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
|
||||
- name: Replicate PyPi Package
|
||||
run: |
|
||||
rm -rf ./dist && rm -rf ./build && rm -rf prowler.egg-info
|
||||
pip install toml
|
||||
python util/replicate_pypi_package.py
|
||||
poetry build
|
||||
- name: Publish prowler-cloud package to PyPI
|
||||
run: |
|
||||
poetry config pypi-token.pypi ${{ secrets.PYPI_API_TOKEN }}
|
||||
poetry publish
|
||||
# Create pull request to github.com/Homebrew/homebrew-core to update prowler formula
|
||||
- name: Bump Homebrew formula
|
||||
uses: mislav/bump-homebrew-formula-action@v2
|
||||
with:
|
||||
formula-name: prowler
|
||||
base-branch: release-${{ env.RELEASE_TAG }}
|
||||
env:
|
||||
COMMITTER_TOKEN: ${{ secrets.PROWLER_ACCESS_TOKEN }}
|
||||
|
||||
5
.gitignore
vendored
@@ -46,3 +46,8 @@ junit-reports/
|
||||
|
||||
# .env
|
||||
.env*
|
||||
|
||||
# Coverage
|
||||
.coverage*
|
||||
.coverage
|
||||
coverage*
|
||||
|
||||
@@ -15,10 +15,11 @@ repos:
|
||||
|
||||
## TOML
|
||||
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
|
||||
rev: v2.7.0
|
||||
rev: v2.10.0
|
||||
hooks:
|
||||
- id: pretty-format-toml
|
||||
args: [--autofix]
|
||||
files: pyproject.toml
|
||||
|
||||
## BASH
|
||||
- repo: https://github.com/koalaman/shellcheck-precommit
|
||||
@@ -27,7 +28,7 @@ repos:
|
||||
- id: shellcheck
|
||||
## PYTHON
|
||||
- repo: https://github.com/myint/autoflake
|
||||
rev: v2.0.1
|
||||
rev: v2.2.0
|
||||
hooks:
|
||||
- id: autoflake
|
||||
args:
|
||||
@@ -44,21 +45,23 @@ repos:
|
||||
args: ["--profile", "black"]
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 23.1.0
|
||||
rev: 22.12.0
|
||||
hooks:
|
||||
- id: black
|
||||
|
||||
- repo: https://github.com/pycqa/flake8
|
||||
rev: 6.0.0
|
||||
rev: 6.1.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
exclude: contrib
|
||||
args: ["--ignore=E266,W503,E203,E501,W605"]
|
||||
|
||||
- repo: https://github.com/haizaar/check-pipfile-lock
|
||||
rev: v0.0.5
|
||||
- repo: https://github.com/python-poetry/poetry
|
||||
rev: 1.6.0 # add version here
|
||||
hooks:
|
||||
- id: check-pipfile-lock
|
||||
- id: poetry-check
|
||||
- id: poetry-lock
|
||||
args: ["--no-update"]
|
||||
|
||||
- repo: https://github.com/hadolint/hadolint
|
||||
rev: v2.12.1-beta
|
||||
@@ -73,6 +76,15 @@ repos:
|
||||
entry: bash -c 'pylint --disable=W,C,R,E -j 0 -rn -sn prowler/'
|
||||
language: system
|
||||
|
||||
- id: trufflehog
|
||||
name: TruffleHog
|
||||
description: Detect secrets in your data.
|
||||
# entry: bash -c 'trufflehog git file://. --only-verified --fail'
|
||||
# For running trufflehog in docker, use the following entry instead:
|
||||
entry: bash -c 'docker run -v "$(pwd):/workdir" -i --rm trufflesecurity/trufflehog:latest git file:///workdir --only-verified --fail'
|
||||
language: system
|
||||
stages: ["commit", "push"]
|
||||
|
||||
- id: pytest-check
|
||||
name: pytest-check
|
||||
entry: bash -c 'pytest tests -n auto'
|
||||
|
||||
13
CONTRIBUTING.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Do you want to learn on how to...
|
||||
|
||||
- Contribute with your code or fixes to Prowler
|
||||
- Create a new check for a provider
|
||||
- Create a new security compliance framework
|
||||
- Add a custom output format
|
||||
- Add a new integration
|
||||
- Contribute with documentation
|
||||
|
||||
Want some swag as appreciation for your contribution?
|
||||
|
||||
# Prowler Developer Guide
|
||||
https://docs.prowler.cloud/en/latest/tutorials/developer-guide/
|
||||
11
Makefile
@@ -2,12 +2,19 @@
|
||||
|
||||
##@ Testing
|
||||
test: ## Test with pytest
|
||||
pytest -n auto -vvv -s -x
|
||||
rm -rf .coverage && \
|
||||
pytest -n auto -vvv -s --cov=./prowler --cov-report=xml tests
|
||||
|
||||
coverage: ## Show Test Coverage
|
||||
coverage run --skip-covered -m pytest -v && \
|
||||
coverage report -m && \
|
||||
rm -rf .coverage
|
||||
rm -rf .coverage && \
|
||||
coverage report -m
|
||||
|
||||
coverage-html: ## Show Test Coverage
|
||||
rm -rf ./htmlcov && \
|
||||
coverage html && \
|
||||
open htmlcov/index.html
|
||||
|
||||
##@ Linting
|
||||
format: ## Format Code
|
||||
|
||||
72
README.md
@@ -11,14 +11,14 @@
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://join.slack.com/t/prowler-workspace/shared_invite/zt-1hix76xsl-2uq222JIXrC7Q8It~9ZNog"><img alt="Slack Shield" src="https://img.shields.io/badge/slack-prowler-brightgreen.svg?logo=slack"></a>
|
||||
<a href="https://pypi.org/project/prowler-cloud/"><img alt="Python Version" src="https://img.shields.io/pypi/v/prowler.svg"></a>
|
||||
<a href="https://pypi.python.org/pypi/prowler-cloud/"><img alt="Python Version" src="https://img.shields.io/pypi/pyversions/prowler.svg"></a>
|
||||
<a href="https://pypistats.org/packages/prowler"><img alt="PyPI Prowler Downloads" src="https://img.shields.io/pypi/dw/prowler.svg"></a>
|
||||
<a href="https://pypistats.org/packages/prowler-cloud"><img alt="PyPI Prowler-Cloud Downloads" src="https://img.shields.io/pypi/dw/prowler-cloud.svg"></a>
|
||||
<a href="https://pypi.org/project/prowler/"><img alt="Python Version" src="https://img.shields.io/pypi/v/prowler.svg"></a>
|
||||
<a href="https://pypi.python.org/pypi/prowler/"><img alt="Python Version" src="https://img.shields.io/pypi/pyversions/prowler.svg"></a>
|
||||
<a href="https://pypistats.org/packages/prowler"><img alt="PyPI Prowler Downloads" src="https://img.shields.io/pypi/dw/prowler.svg?label=prowler%20downloads"></a>
|
||||
<a href="https://pypistats.org/packages/prowler-cloud"><img alt="PyPI Prowler-Cloud Downloads" src="https://img.shields.io/pypi/dw/prowler-cloud.svg?label=prowler-cloud%20downloads"></a>
|
||||
<a href="https://hub.docker.com/r/toniblyx/prowler"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/toniblyx/prowler"></a>
|
||||
<a href="https://hub.docker.com/r/toniblyx/prowler"><img alt="Docker" src="https://img.shields.io/docker/cloud/build/toniblyx/prowler"></a>
|
||||
<a href="https://hub.docker.com/r/toniblyx/prowler"><img alt="Docker" src="https://img.shields.io/docker/image-size/toniblyx/prowler"></a>
|
||||
<a href="https://gallery.ecr.aws/o4g1s5r6/prowler"><img width="120" height=19" alt="AWS ECR Gallery" src="https://user-images.githubusercontent.com/3985464/151531396-b6535a68-c907-44eb-95a1-a09508178616.png"></a>
|
||||
<a href="https://gallery.ecr.aws/prowler-cloud/prowler"><img width="120" height=19" alt="AWS ECR Gallery" src="https://user-images.githubusercontent.com/3985464/151531396-b6535a68-c907-44eb-95a1-a09508178616.png"></a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/prowler-cloud/prowler"><img alt="Repo size" src="https://img.shields.io/github/repo-size/prowler-cloud/prowler"></a>
|
||||
@@ -33,12 +33,24 @@
|
||||
|
||||
# Description
|
||||
|
||||
`Prowler` is an Open Source security tool to perform AWS and Azure security best practices assessments, audits, incident response, continuous monitoring, hardening and forensics readiness.
|
||||
`Prowler` is an Open Source security tool to perform AWS, GCP and Azure security best practices assessments, audits, incident response, continuous monitoring, hardening and forensics readiness.
|
||||
|
||||
It contains hundreds of controls covering CIS, PCI-DSS, ISO27001, GDPR, HIPAA, FFIEC, SOC2, AWS FTR, ENS and custom security frameworks.
|
||||
It contains hundreds of controls covering CIS, NIST 800, NIST CSF, CISA, RBI, FedRAMP, PCI-DSS, GDPR, HIPAA, FFIEC, SOC2, GXP, AWS Well-Architected Framework Security Pillar, AWS Foundational Technical Review (FTR), ENS (Spanish National Security Scheme) and your custom security frameworks.
|
||||
|
||||
| Provider | Checks | Services | [Compliance Frameworks](https://docs.prowler.cloud/en/latest/tutorials/compliance/) | [Categories](https://docs.prowler.cloud/en/latest/tutorials/misc/#categories) |
|
||||
|---|---|---|---|---|
|
||||
| AWS | 290 | 56 -> `prowler aws --list-services` | 25 -> `prowler aws --list-compliance` | 5 -> `prowler aws --list-categories` |
|
||||
| GCP | 73 | 11 -> `prowler gcp --list-services` | 1 -> `prowler gcp --list-compliance` | 2 -> `prowler gcp --list-categories`|
|
||||
| Azure | 23 | 4 -> `prowler azure --list-services` | CIS soon | 1 -> `prowler azure --list-categories` |
|
||||
| Kubernetes | Planned | - | - | - |
|
||||
|
||||
# 📖 Documentation
|
||||
|
||||
The full documentation can now be found at [https://docs.prowler.cloud](https://docs.prowler.cloud)
|
||||
|
||||
## Looking for Prowler v2 documentation?
|
||||
For Prowler v2 Documentation, please go to https://github.com/prowler-cloud/prowler/tree/2.12.1.
|
||||
|
||||
# ⚙️ Install
|
||||
|
||||
## Pip package
|
||||
@@ -48,6 +60,7 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler-clo
|
||||
pip install prowler
|
||||
prowler -v
|
||||
```
|
||||
More details at https://docs.prowler.cloud
|
||||
|
||||
## Containers
|
||||
|
||||
@@ -60,7 +73,7 @@ The available versions of Prowler are the following:
|
||||
The container images are available here:
|
||||
|
||||
- [DockerHub](https://hub.docker.com/r/toniblyx/prowler/tags)
|
||||
- [AWS Public ECR](https://gallery.ecr.aws/o4g1s5r6/prowler)
|
||||
- [AWS Public ECR](https://gallery.ecr.aws/prowler-cloud/prowler)
|
||||
|
||||
## From Github
|
||||
|
||||
@@ -74,20 +87,15 @@ poetry install
|
||||
python prowler.py -v
|
||||
```
|
||||
|
||||
# 📖 Documentation
|
||||
|
||||
The full documentation can now be found at [https://docs.prowler.cloud](https://docs.prowler.cloud)
|
||||
|
||||
|
||||
# 📐✏️ High level architecture
|
||||
|
||||
You can run Prowler from your workstation, an EC2 instance, Fargate or any other container, Codebuild, CloudShell and Cloud9.
|
||||
|
||||

|
||||

|
||||
|
||||
# 📝 Requirements
|
||||
|
||||
Prowler has been written in Python using the [AWS SDK (Boto3)](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html#) and [Azure SDK](https://azure.github.io/azure-sdk-for-python/).
|
||||
Prowler has been written in Python using the [AWS SDK (Boto3)](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html#), [Azure SDK](https://azure.github.io/azure-sdk-for-python/) and [GCP API Python Client](https://github.com/googleapis/google-api-python-client/).
|
||||
## AWS
|
||||
|
||||
Since Prowler uses AWS Credentials under the hood, you can follow any authentication method as described [here](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-precedence).
|
||||
@@ -107,8 +115,8 @@ Make sure you have properly configured your AWS-CLI with a valid Access Key and
|
||||
|
||||
Those credentials must be associated to a user or role with proper permissions to do all checks. To make sure, add the following AWS managed policies to the user or role being used:
|
||||
|
||||
- arn:aws:iam::aws:policy/SecurityAudit
|
||||
- arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
|
||||
- `arn:aws:iam::aws:policy/SecurityAudit`
|
||||
- `arn:aws:iam::aws:policy/job-function/ViewOnlyAccess`
|
||||
|
||||
> Moreover, some read-only additional permissions are needed for several checks, make sure you attach also the custom policy [prowler-additions-policy.json](https://github.com/prowler-cloud/prowler/blob/master/permissions/prowler-additions-policy.json) to the role you are using.
|
||||
|
||||
@@ -136,7 +144,7 @@ export AZURE_CLIENT_SECRET="XXXXXXX"
|
||||
If you try to execute Prowler with the `--sp-env-auth` flag and those variables are empty or not exported, the execution is going to fail.
|
||||
### AZ CLI / Browser / Managed Identity authentication
|
||||
|
||||
The other three cases do not need additional configuration, `--az-cli-auth` and `--managed-identity-auth` are automated options, `--browser-auth` needs the user to authenticate using the default browser to start the scan.
|
||||
The other three cases do not need additional configuration, `--az-cli-auth` and `--managed-identity-auth` are automated options, `--browser-auth` needs the user to authenticate using the default browser to start the scan. Also `--browser-auth` needs the tenant id to be specified with `--tenant-id`.
|
||||
|
||||
### Permissions
|
||||
|
||||
@@ -162,6 +170,22 @@ Regarding the subscription scope, Prowler by default scans all the subscriptions
|
||||
- `Reader`
|
||||
|
||||
|
||||
## Google Cloud Platform
|
||||
|
||||
Prowler will follow the same credentials search as [Google authentication libraries](https://cloud.google.com/docs/authentication/application-default-credentials#search_order):
|
||||
|
||||
1. [GOOGLE_APPLICATION_CREDENTIALS environment variable](https://cloud.google.com/docs/authentication/application-default-credentials#GAC)
|
||||
2. [User credentials set up by using the Google Cloud CLI](https://cloud.google.com/docs/authentication/application-default-credentials#personal)
|
||||
3. [The attached service account, returned by the metadata server](https://cloud.google.com/docs/authentication/application-default-credentials#attached-sa)
|
||||
|
||||
Those credentials must be associated to a user or service account with proper permissions to do all checks. To make sure, add the following roles to the member associated with the credentials:
|
||||
|
||||
- Viewer
|
||||
- Security Reviewer
|
||||
- Stackdriver Account Viewer
|
||||
|
||||
> By default, `prowler` will scan all accessible GCP Projects, use flag `--project-ids` to specify the projects to be scanned.
|
||||
|
||||
# 💻 Basic Usage
|
||||
|
||||
To run prowler, you will need to specify the provider (e.g aws or azure):
|
||||
@@ -236,12 +260,14 @@ prowler azure [--sp-env-auth, --az-cli-auth, --browser-auth, --managed-identity-
|
||||
```
|
||||
> By default, `prowler` will scan all Azure subscriptions.
|
||||
|
||||
# 🎉 New Features
|
||||
## Google Cloud Platform
|
||||
|
||||
- Python: we got rid of all bash and it is now all in Python.
|
||||
- Faster: huge performance improvements (same account from 2.5 hours to 4 minutes).
|
||||
- Developers and community: we have made it easier to contribute with new checks and new compliance frameworks. We also included unit tests.
|
||||
- Multi-cloud: in addition to AWS, we have added Azure, we plan to include GCP and OCI soon, let us know if you want to contribute!
|
||||
Optionally, you can provide the location of an application credential JSON file with the following argument:
|
||||
|
||||
```console
|
||||
prowler gcp --credentials-file path
|
||||
```
|
||||
> By default, `prowler` will scan all accessible GCP Projects, use flag `--project-ids` to specify the projects to be scanned.
|
||||
|
||||
# 📃 License
|
||||
|
||||
|
||||
@@ -1,45 +1,24 @@
|
||||
# Build command
|
||||
# docker build --platform=linux/amd64 --no-cache -t prowler:latest .
|
||||
|
||||
FROM public.ecr.aws/amazonlinux/amazonlinux:2022
|
||||
ARG PROWLER_VERSION=latest
|
||||
|
||||
ARG PROWLERVER=2.9.0
|
||||
ARG USERNAME=prowler
|
||||
ARG USERID=34000
|
||||
FROM toniblyx/prowler:${PROWLER_VERSION}
|
||||
|
||||
# Install Dependencies
|
||||
RUN \
|
||||
dnf update -y && \
|
||||
dnf install -y bash file findutils git jq python3 python3-pip \
|
||||
python3-setuptools python3-wheel shadow-utils tar unzip which && \
|
||||
dnf remove -y awscli && \
|
||||
dnf clean all && \
|
||||
useradd -l -s /bin/sh -U -u ${USERID} ${USERNAME} && \
|
||||
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
|
||||
unzip awscliv2.zip && \
|
||||
./aws/install && \
|
||||
pip3 install --no-cache-dir --upgrade pip && \
|
||||
pip3 install --no-cache-dir "git+https://github.com/ibm/detect-secrets.git@master#egg=detect-secrets" && \
|
||||
rm -rf aws awscliv2.zip /var/cache/dnf
|
||||
USER 0
|
||||
# hadolint ignore=DL3018
|
||||
RUN apk --no-cache add bash aws-cli jq
|
||||
|
||||
# Place script and env vars
|
||||
COPY .awsvariables run-prowler-securityhub.sh /
|
||||
ARG MULTI_ACCOUNT_SECURITY_HUB_PATH=/home/prowler/multi-account-securityhub
|
||||
|
||||
# Installs prowler and change permissions
|
||||
RUN \
|
||||
curl -L "https://github.com/prowler-cloud/prowler/archive/refs/tags/${PROWLERVER}.tar.gz" -o "prowler.tar.gz" && \
|
||||
tar xvzf prowler.tar.gz && \
|
||||
rm -f prowler.tar.gz && \
|
||||
mv prowler-${PROWLERVER} prowler && \
|
||||
chown ${USERNAME}:${USERNAME} /run-prowler-securityhub.sh && \
|
||||
chmod 500 /run-prowler-securityhub.sh && \
|
||||
chown ${USERNAME}:${USERNAME} /.awsvariables && \
|
||||
chmod 400 /.awsvariables && \
|
||||
chown ${USERNAME}:${USERNAME} -R /prowler && \
|
||||
chmod +x /prowler/prowler
|
||||
USER prowler
|
||||
|
||||
# Drop to user
|
||||
USER ${USERNAME}
|
||||
# Move script and environment variables
|
||||
RUN mkdir "${MULTI_ACCOUNT_SECURITY_HUB_PATH}"
|
||||
COPY --chown=prowler:prowler .awsvariables run-prowler-securityhub.sh "${MULTI_ACCOUNT_SECURITY_HUB_PATH}"/
|
||||
RUN chmod 500 "${MULTI_ACCOUNT_SECURITY_HUB_PATH}"/run-prowler-securityhub.sh & \
|
||||
chmod 400 "${MULTI_ACCOUNT_SECURITY_HUB_PATH}"/.awsvariables
|
||||
|
||||
# Run script
|
||||
ENTRYPOINT ["/run-prowler-securityhub.sh"]
|
||||
WORKDIR ${MULTI_ACCOUNT_SECURITY_HUB_PATH}
|
||||
|
||||
ENTRYPOINT ["./run-prowler-securityhub.sh"]
|
||||
|
||||
51
contrib/multi-account-securityhub/run-prowler-securityhub.sh
Normal file → Executable file
@@ -1,20 +1,17 @@
|
||||
#!/bin/bash
|
||||
# Run Prowler against All AWS Accounts in an AWS Organization
|
||||
|
||||
# Change Directory (rest of the script, assumes you're in the root directory)
|
||||
cd / || exit
|
||||
|
||||
# Show Prowler Version
|
||||
./prowler/prowler -V
|
||||
prowler -v
|
||||
|
||||
# Source .awsvariables
|
||||
# shellcheck disable=SC1091
|
||||
source .awsvariables
|
||||
|
||||
# Get Values from Environment Variables
|
||||
echo "ROLE: $ROLE"
|
||||
echo "PARALLEL_ACCOUNTS: $PARALLEL_ACCOUNTS"
|
||||
echo "REGION: $REGION"
|
||||
echo "ROLE: ${ROLE}"
|
||||
echo "PARALLEL_ACCOUNTS: ${PARALLEL_ACCOUNTS}"
|
||||
echo "REGION: ${REGION}"
|
||||
|
||||
# Function to unset AWS Profile Variables
|
||||
unset_aws() {
|
||||
@@ -24,33 +21,33 @@ unset_aws
|
||||
|
||||
# Find THIS Account AWS Number
|
||||
CALLER_ARN=$(aws sts get-caller-identity --output text --query "Arn")
|
||||
PARTITION=$(echo "$CALLER_ARN" | cut -d: -f2)
|
||||
THISACCOUNT=$(echo "$CALLER_ARN" | cut -d: -f5)
|
||||
echo "THISACCOUNT: $THISACCOUNT"
|
||||
echo "PARTITION: $PARTITION"
|
||||
PARTITION=$(echo "${CALLER_ARN}" | cut -d: -f2)
|
||||
THISACCOUNT=$(echo "${CALLER_ARN}" | cut -d: -f5)
|
||||
echo "THISACCOUNT: ${THISACCOUNT}"
|
||||
echo "PARTITION: ${PARTITION}"
|
||||
|
||||
# Function to Assume Role to THIS Account & Create Session
|
||||
this_account_session() {
|
||||
unset_aws
|
||||
role_credentials=$(aws sts assume-role --role-arn arn:"$PARTITION":iam::"$THISACCOUNT":role/"$ROLE" --role-session-name ProwlerRun --output json)
|
||||
AWS_ACCESS_KEY_ID=$(echo "$role_credentials" | jq -r .Credentials.AccessKeyId)
|
||||
AWS_SECRET_ACCESS_KEY=$(echo "$role_credentials" | jq -r .Credentials.SecretAccessKey)
|
||||
AWS_SESSION_TOKEN=$(echo "$role_credentials" | jq -r .Credentials.SessionToken)
|
||||
role_credentials=$(aws sts assume-role --role-arn arn:"${PARTITION}":iam::"${THISACCOUNT}":role/"${ROLE}" --role-session-name ProwlerRun --output json)
|
||||
AWS_ACCESS_KEY_ID=$(echo "${role_credentials}" | jq -r .Credentials.AccessKeyId)
|
||||
AWS_SECRET_ACCESS_KEY=$(echo "${role_credentials}" | jq -r .Credentials.SecretAccessKey)
|
||||
AWS_SESSION_TOKEN=$(echo "${role_credentials}" | jq -r .Credentials.SessionToken)
|
||||
export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
|
||||
}
|
||||
|
||||
# Find AWS Master Account
|
||||
this_account_session
|
||||
AWSMASTER=$(aws organizations describe-organization --query Organization.MasterAccountId --output text)
|
||||
echo "AWSMASTER: $AWSMASTER"
|
||||
echo "AWSMASTER: ${AWSMASTER}"
|
||||
|
||||
# Function to Assume Role to Master Account & Create Session
|
||||
master_account_session() {
|
||||
unset_aws
|
||||
role_credentials=$(aws sts assume-role --role-arn arn:"$PARTITION":iam::"$AWSMASTER":role/"$ROLE" --role-session-name ProwlerRun --output json)
|
||||
AWS_ACCESS_KEY_ID=$(echo "$role_credentials" | jq -r .Credentials.AccessKeyId)
|
||||
AWS_SECRET_ACCESS_KEY=$(echo "$role_credentials" | jq -r .Credentials.SecretAccessKey)
|
||||
AWS_SESSION_TOKEN=$(echo "$role_credentials" | jq -r .Credentials.SessionToken)
|
||||
role_credentials=$(aws sts assume-role --role-arn arn:"${PARTITION}":iam::"${AWSMASTER}":role/"${ROLE}" --role-session-name ProwlerRun --output json)
|
||||
AWS_ACCESS_KEY_ID=$(echo "${role_credentials}" | jq -r .Credentials.AccessKeyId)
|
||||
AWS_SECRET_ACCESS_KEY=$(echo "${role_credentials}" | jq -r .Credentials.SecretAccessKey)
|
||||
AWS_SESSION_TOKEN=$(echo "${role_credentials}" | jq -r .Credentials.SessionToken)
|
||||
export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
|
||||
}
|
||||
|
||||
@@ -60,20 +57,20 @@ ACCOUNTS_IN_ORGS=$(aws organizations list-accounts --query Accounts[*].Id --outp
|
||||
|
||||
# Run Prowler against Accounts in AWS Organization
|
||||
echo "AWS Accounts in Organization"
|
||||
echo "$ACCOUNTS_IN_ORGS"
|
||||
for accountId in $ACCOUNTS_IN_ORGS; do
|
||||
echo "${ACCOUNTS_IN_ORGS}"
|
||||
for accountId in ${ACCOUNTS_IN_ORGS}; do
|
||||
# shellcheck disable=SC2015
|
||||
test "$(jobs | wc -l)" -ge $PARALLEL_ACCOUNTS && wait -n || true
|
||||
test "$(jobs | wc -l)" -ge "${PARALLEL_ACCOUNTS}" && wait -n || true
|
||||
{
|
||||
START_TIME=$SECONDS
|
||||
START_TIME=${SECONDS}
|
||||
# Unset AWS Profile Variables
|
||||
unset_aws
|
||||
# Run Prowler
|
||||
echo -e "Assessing AWS Account: $accountId, using Role: $ROLE on $(date)"
|
||||
echo -e "Assessing AWS Account: ${accountId}, using Role: ${ROLE} on $(date)"
|
||||
# Pipe stdout to /dev/null to reduce unnecessary Cloudwatch logs
|
||||
./prowler/prowler -R "$ROLE" -A "$accountId" -M json-asff -q -S -f "$REGION" > /dev/null
|
||||
prowler aws -R arn:"${PARTITION}":iam::"${accountId}":role/"${ROLE}" -q -S -f "${REGION}" > /dev/null
|
||||
TOTAL_SEC=$((SECONDS - START_TIME))
|
||||
printf "Completed AWS Account: $accountId in %02dh:%02dm:%02ds" $((TOTAL_SEC / 3600)) $((TOTAL_SEC % 3600 / 60)) $((TOTAL_SEC % 60))
|
||||
printf "Completed AWS Account: ${accountId} in %02dh:%02dm:%02ds" $((TOTAL_SEC / 3600)) $((TOTAL_SEC % 3600 / 60)) $((TOTAL_SEC % 60))
|
||||
echo ""
|
||||
} &
|
||||
done
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Organizational Prowler with Serverless
|
||||
|
||||
Langage: [Korean](README_kr.md)
|
||||
Language: [Korean](README_kr.md)
|
||||
|
||||
This project is created to apply prowler in a multi-account environment within AWS Organizations.
|
||||
CloudWatch triggers CodeBuild every fixed time.
|
||||
@@ -18,12 +18,12 @@ For more information on how to use prowler, see [here](https://github.com/prowle
|
||||
2. **Master Account**
|
||||
1. Deploy [ProwlerRole.yaml](templates/ProwlerRole.yaml) stack to CloudFormation in a bid to create resources to master account itself.
|
||||
(The template will be also deployed for other member accounts as a StackSet)
|
||||
- ProwlerCodeBuildAccount : Audit Acccount ID where CodeBuild resides. (preferably Audit/Security account)
|
||||
- ProwlerCodeBuildAccount : Audit Account ID where CodeBuild resides. (preferably Audit/Security account)
|
||||
- ProwlerCodeBuildRole : Role name to use in CodeBuild service
|
||||
- ProwlerCrossAccountRole : Role name to assume for Cross account
|
||||
- ProwlerS3 : The S3 bucket name where reports will be put
|
||||
1. Create **StackSet** with [ProwlerRole.yaml](templates/ProwlerRole.yaml) to deploy Role into member accounts in AWS Organizations.
|
||||
- ProwlerCodeBuildAccount : Audit Acccount ID where CodeBuild resides. (preferably Audit/Security account)
|
||||
- ProwlerCodeBuildAccount : Audit Account ID where CodeBuild resides. (preferably Audit/Security account)
|
||||
- ProwlerCodeBuildRole : Role name to use in CodeBuild service
|
||||
- ProwlerCrossAccountRole : Role name to assume for Cross account
|
||||
- ProwlerS3 : The S3 bucket name where reports will be put
|
||||
@@ -45,4 +45,4 @@ For more information on how to use prowler, see [here](https://github.com/prowle
|
||||
- ProwlerReportS3Account : The account where the report S3 bucket resides.
|
||||
1. If you'd like to change the scheduled time,
|
||||
1. You can change the cron expression of ScheduleExpression within [ProwlerCodeBuildStack.yaml](templates/ProwlerCodeBuildStack.yaml).
|
||||
2. Alternatively, you can make changes directrly from Events > Rules > ProwlerExecuteRule > Actions > Edit in CloudWatch console.
|
||||
2. Alternatively, you can make changes directly from Events > Rules > ProwlerExecuteRule > Actions > Edit in CloudWatch console.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Organizational Prowler with Serverless
|
||||
|
||||
Langage: [English](README.md)
|
||||
Language: [English](README.md)
|
||||
|
||||
이 문서는 AWS Organization 내의 multi account 환경에서 prowler 를 적용하기 위해 작성된 문서입니다.
|
||||
일정 시간마다 CloudWatch는 CodeBuild 를 트리거합니다.
|
||||
@@ -22,7 +22,7 @@ prowler 의 자세한 사용방법은 [이 곳](https://github.com/prowler-cloud
|
||||
|
||||
[ProwlerRole.yaml](templates/ProwlerRole.yaml)
|
||||
|
||||
- ProwlerCodeBuildAccount : CodeBuild 가 있는 Audit Acccount ID
|
||||
- ProwlerCodeBuildAccount : CodeBuild 가 있는 Audit Account ID
|
||||
- ProwlerCodeBuildRole : CodeBuild의 생성될 Role 이름
|
||||
- ProwlerCrossAccountRole : Cross account 용 Assume할 Role 이름
|
||||
- ProwlerS3 : report 가 저장될 S3 bucket 명
|
||||
@@ -30,7 +30,7 @@ prowler 의 자세한 사용방법은 [이 곳](https://github.com/prowler-cloud
|
||||
|
||||
[ProwlerRole.yaml](templates/ProwlerRole.yaml)
|
||||
|
||||
- ProwlerCodeBuildAccount : CodeBuild 가 있는 Audit Acccount
|
||||
- ProwlerCodeBuildAccount : CodeBuild 가 있는 Audit Account
|
||||
- ProwlerCodeBuildRole : CodeBuild에서 사용할 Role 이름
|
||||
- ProwlerCrossAccountRole : Cross account 용 Assume할 Role 이름
|
||||
- ProwlerS3 : report 가 저장될 S3 bucket 명
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Introduction
|
||||
|
||||
The following demonstartes how to quickly install the resources necessary to perform a security baseline using Prowler. The speed is based on the prebuilt terraform module that can configure all the resources necessuary to run Prowler with the findings being sent to AWS Security Hub.
|
||||
The following demonstrates how to quickly install the resources necessary to perform a security baseline using Prowler. The speed is based on the prebuilt terraform module that can configure all the resources necessary to run Prowler with the findings being sent to AWS Security Hub.
|
||||
|
||||
## Install
|
||||
|
||||
@@ -24,7 +24,7 @@ Installing Prowler with Terraform is simple and can be completed in under 1 minu
|
||||
|
||||

|
||||
|
||||
- It is likely an error will return related to the SecurityHub subscription. This appears to be Terraform related and you can validate the configuration by navigating to the SecurityHub console. Click Integreations and search for Prowler. Take note of the green check where it says *Accepting findings*
|
||||
- It is likely an error will return related to the SecurityHub subscription. This appears to be Terraform related and you can validate the configuration by navigating to the SecurityHub console. Click Integrations and search for Prowler. Take note of the green check where it says *Accepting findings*
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ To make sure rules are working fine, run `/var/ossec/bin/ossec-logtest` and copy
|
||||
```
|
||||
You must see 3 phases goin on.
|
||||
|
||||
To check if there is any error you can enable the debug mode of `modulesd` setting the `wazuh_modules.debug=0` variable to 2 in `/var/ossec/etc/internal_options.conf` file. Restart wazun-manager and errors should appear in the `/var/ossec/logs/ossec.log` file.
|
||||
To check if there is any error you can enable the debug mode of `modulesd` setting the `wazuh_modules.debug=0` variable to 2 in `/var/ossec/etc/internal_options.conf` file. Restart wazuh-manager and errors should appear in the `/var/ossec/logs/ossec.log` file.
|
||||
|
||||
## Thanks
|
||||
|
||||
|
||||
9
docs/developer-guide/audit-info.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Audit Info
|
||||
|
||||
In each Prowler provider we have a Python object called `audit_info` which is in charge of keeping the credentials, the configuration and the state of each audit, and it's passed to each service during the `__init__`.
|
||||
|
||||
- AWS: https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/aws/lib/audit_info/models.py#L34-L54
|
||||
- GCP: https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/aws/lib/audit_info/models.py#L7-L30
|
||||
- Azure: https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/azure/lib/audit_info/models.py#L17-L31
|
||||
|
||||
This `audit_info` object is shared during the Prowler execution and for that reason is important to mock it in each test to isolate them. See the [testing guide](./unit-testing.md) for more information.
|
||||
309
docs/developer-guide/checks.md
Normal file
@@ -0,0 +1,309 @@
|
||||
# Create a new Check for a Provider
|
||||
|
||||
Here you can find how to create new checks for Prowler.
|
||||
|
||||
**To create a check is required to have a Prowler provider service already created, so if the service is not present or the attribute you want to audit is not retrieved by the service, please refer to the [Service](./services.md) documentation.**
|
||||
|
||||
## Introduction
|
||||
To create a new check for a supported Prowler provider, you will need to create a folder with the check name inside the specific service for the selected provider.
|
||||
|
||||
We are going to use the `ec2_ami_public` check form the `AWS` provider as an example. So the folder name will `prowler/providers/aws/services/ec2/ec2_ami_public` (following the format `prowler/providers/<provider>/services/<service>/<check_name>`), with the name of check following the pattern: `service_subservice/resource_action`.
|
||||
|
||||
Inside that folder, we need to create three files:
|
||||
|
||||
- An empty `__init__.py`: to make Python treat this check folder as a package.
|
||||
- A `check_name.py` with the above format containing the check's logic. Refer to the [check](./checks.md#check)
|
||||
- A `check_name.metadata.json` containing the check's metadata. Refer to the [check metadata](./checks.md#check-metadata)
|
||||
|
||||
## Check
|
||||
|
||||
The Prowler's check structure is very simple and following it there is nothing more to do to include a check in a provider's service because the load is done dynamically based on the paths.
|
||||
|
||||
The following is the code for the `ec2_ami_public` check:
|
||||
```python title="Check Class"
|
||||
# At the top of the file we need to import the following:
|
||||
# - Check class which is in charge of the following:
|
||||
# - Retrieve the check metadata and expose the `metadata()`
|
||||
# to return a JSON representation of the metadata,
|
||||
# read more at Check Metadata Model down below.
|
||||
# - Enforce that each check requires to have the `execute()` function
|
||||
from prowler.lib.check.models import Check, Check_Report_AWS
|
||||
|
||||
# Then you have to import the provider service client
|
||||
# read more at the Service documentation.
|
||||
from prowler.providers.aws.services.ec2.ec2_client import ec2_client
|
||||
|
||||
# For each check we need to create a python class called the same as the
|
||||
# file which inherits from the Check class.
|
||||
class ec2_ami_public(Check):
|
||||
"""ec2_ami_public verifies if an EC2 AMI is publicly shared"""
|
||||
|
||||
# Then, within the check's class we need to create the "execute(self)"
|
||||
# function, which is enforce by the "Check" class to implement
|
||||
# the Check's interface and let Prowler to run this check.
|
||||
def execute(self):
|
||||
|
||||
# Inside the execute(self) function we need to create
|
||||
# the list of findings initialised to an empty list []
|
||||
findings = []
|
||||
|
||||
# Then, using the service client we need to iterate by the resource we
|
||||
# want to check, in this case EC2 AMIs stored in the
|
||||
# "ec2_client.images" object.
|
||||
for image in ec2_client.images:
|
||||
|
||||
# Once iterating for the images, we have to intialise
|
||||
# the Check_Report_AWS class passing the check's metadata
|
||||
# using the "metadata" function explained above.
|
||||
report = Check_Report_AWS(self.metadata())
|
||||
|
||||
# For each Prowler check we MUST fill the following
|
||||
# Check_Report_AWS fields:
|
||||
# - region
|
||||
# - resource_id
|
||||
# - resource_arn
|
||||
# - resource_tags
|
||||
# - status
|
||||
# - status_extended
|
||||
report.region = image.region
|
||||
report.resource_id = image.id
|
||||
report.resource_arn = image.arn
|
||||
# The resource_tags should be filled if the resource has the ability
|
||||
# of having tags, please check the service first.
|
||||
report.resource_tags = image.tags
|
||||
|
||||
# Then we need to create the business logic for the check
|
||||
# which always should be simple because the Prowler service
|
||||
# must do the heavy lifting and the check should be in charge
|
||||
# of parsing the data provided
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"EC2 AMI {image.id} is not public."
|
||||
|
||||
# In this example each "image" object has a boolean attribute
|
||||
# called "public" to set if the AMI is publicly shared
|
||||
if image.public:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
f"EC2 AMI {image.id} is currently public."
|
||||
)
|
||||
|
||||
# Then at the same level as the "report"
|
||||
# object we need to append it to the findings list.
|
||||
findings.append(report)
|
||||
|
||||
# Last thing to do is to return the findings list to Prowler
|
||||
return findings
|
||||
```
|
||||
|
||||
### Check Status
|
||||
|
||||
All the checks MUST fill the `report.status` and `report.status_extended` with the following criteria:
|
||||
|
||||
- Status -- `report.status`
|
||||
- `PASS` --> If the check is passing against the configured value.
|
||||
- `FAIL` --> If the check is passing against the configured value.
|
||||
- `INFO` --> This value cannot be used unless a manual operation is required in order to determine if the `report.status` is whether `PASS` or `FAIL`.
|
||||
- Status Extended -- `report.status_extended`
|
||||
- MUST end in a dot `.`
|
||||
- MUST include the service audited with the resource and a brief explanation of the result generated, e.g.: `EC2 AMI ami-0123456789 is not public.`
|
||||
|
||||
### Resource ID, Name and ARN
|
||||
All the hecks must fill the `report.resource_id` and `report.resource_arn` with the following criteria:
|
||||
|
||||
- AWS
|
||||
- Resource ID -- `report.resource_id`
|
||||
- AWS Account --> Account Number `123456789012`
|
||||
- AWS Resource --> Resource ID / Name
|
||||
- Root resource --> `<root_account>`
|
||||
- Resource ARN -- `report.resource_arn`
|
||||
- AWS Account --> Root ARN `arn:aws:iam::123456789012:root`
|
||||
- AWS Resource --> Resource ARN
|
||||
- Root resource --> Root ARN `arn:aws:iam::123456789012:root`
|
||||
- GCP
|
||||
- Resource ID -- `report.resource_id`
|
||||
- GCP Resource --> Resource ID
|
||||
- Resource Name -- `report.resource_name`
|
||||
- GCP Resource --> Resource Name
|
||||
- Azure
|
||||
- Resource ID -- `report.resource_id`
|
||||
- Azure Resource --> Resource ID
|
||||
- Resource Name -- `report.resource_name`
|
||||
- Azure Resource --> Resource Name
|
||||
|
||||
### Python Model
|
||||
The following is the Python model for the check's class.
|
||||
|
||||
As per August 5th 2023 the `Check_Metadata_Model` can be found [here](https://github.com/prowler-cloud/prowler/blob/master/prowler/lib/check/models.py#L59-L80).
|
||||
|
||||
```python
|
||||
class Check(ABC, Check_Metadata_Model):
|
||||
"""Prowler Check"""
|
||||
|
||||
def __init__(self, **data):
|
||||
"""Check's init function. Calls the CheckMetadataModel init."""
|
||||
# Parse the Check's metadata file
|
||||
metadata_file = (
|
||||
os.path.abspath(sys.modules[self.__module__].__file__)[:-3]
|
||||
+ ".metadata.json"
|
||||
)
|
||||
# Store it to validate them with Pydantic
|
||||
data = Check_Metadata_Model.parse_file(metadata_file).dict()
|
||||
# Calls parents init function
|
||||
super().__init__(**data)
|
||||
|
||||
def metadata(self) -> dict:
|
||||
"""Return the JSON representation of the check's metadata"""
|
||||
return self.json()
|
||||
|
||||
@abstractmethod
|
||||
def execute(self):
|
||||
"""Execute the check's logic"""
|
||||
```
|
||||
|
||||
### Using the audit config
|
||||
|
||||
Prowler has a [configuration file](../tutorials/configuration_file.md) which is used to pass certain configuration values to the checks, like the following:
|
||||
|
||||
```python title="ec2_securitygroup_with_many_ingress_egress_rules.py"
|
||||
class ec2_securitygroup_with_many_ingress_egress_rules(Check):
|
||||
def execute(self):
|
||||
findings = []
|
||||
|
||||
# max_security_group_rules, default: 50
|
||||
max_security_group_rules = ec2_client.audit_config.get(
|
||||
"max_security_group_rules", 50
|
||||
)
|
||||
for security_group in ec2_client.security_groups:
|
||||
```
|
||||
|
||||
```yaml title="config.yaml"
|
||||
# AWS Configuration
|
||||
aws:
|
||||
# AWS EC2 Configuration
|
||||
|
||||
# aws.ec2_securitygroup_with_many_ingress_egress_rules
|
||||
# The default value is 50 rules
|
||||
max_security_group_rules: 50
|
||||
```
|
||||
|
||||
As you can see in the above code, within the service client, in this case the `ec2_client`, there is an object called `audit_config` which is a Python dictionary containing the values read from the configuration file.
|
||||
|
||||
In order to use it, you have to check first if the value is present in the configuration file. If the value is not present, you can create it in the `config.yaml` file and then, read it from the check.
|
||||
> It is mandatory to always use the `dictionary.get(value, default)` syntax to set a default value in the case the configuration value is not present.
|
||||
|
||||
|
||||
## Check Metadata
|
||||
|
||||
Each Prowler check has metadata associated which is stored at the same level of the check's folder in a file called A `check_name.metadata.json` containing the check's metadata.
|
||||
|
||||
> We are going to include comments in this example metadata JSON but they cannot be included because the JSON format does not allow comments.
|
||||
|
||||
```json
|
||||
{
|
||||
# Provider holds the Prowler provider which the checks belongs to
|
||||
"Provider": "aws",
|
||||
# CheckID holds check name
|
||||
"CheckID": "ec2_ami_public",
|
||||
# CheckTitle holds the title of the check
|
||||
"CheckTitle": "Ensure there are no EC2 AMIs set as Public.",
|
||||
# CheckType holds Software and Configuration Checks, check more here
|
||||
# https://docs.aws.amazon.com/securityhub/latest/userguide/asff-required-attributes.html#Types
|
||||
"CheckType": [
|
||||
"Infrastructure Security"
|
||||
],
|
||||
# ServiceName holds the provider service name
|
||||
"ServiceName": "ec2",
|
||||
# SubServiceName holds the service's subservice or resource used by the check
|
||||
"SubServiceName": "ami",
|
||||
# ResourceIdTemplate holds the unique ID for the resource used by the check
|
||||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
||||
# Severity holds the check's severity, always in lowercase (critical, high, medium, low or informational)
|
||||
"Severity": "critical",
|
||||
# ResourceType only for AWS, holds the type from here
|
||||
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html
|
||||
"ResourceType": "Other",
|
||||
# Description holds the title of the check, for now is the same as CheckTitle
|
||||
"Description": "Ensure there are no EC2 AMIs set as Public.",
|
||||
# Risk holds the check risk if the result is FAIL
|
||||
"Risk": "When your AMIs are publicly accessible, they are available in the Community AMIs where everyone with an AWS account can use them to launch EC2 instances. Your AMIs could contain snapshots of your applications (including their data), therefore exposing your snapshots in this manner is not advised.",
|
||||
# RelatedUrl holds an URL with more information about the check purpose
|
||||
"RelatedUrl": "",
|
||||
# Remediation holds the information to help the practitioner to fix the issue in the case of the check raise a FAIL
|
||||
"Remediation": {
|
||||
# Code holds different methods to remediate the FAIL finding
|
||||
"Code": {
|
||||
# CLI holds the command in the provider native CLI to remediate it
|
||||
"CLI": "https://docs.bridgecrew.io/docs/public_8#cli-command",
|
||||
# NativeIaC holds the native IaC code to remediate it, use "https://docs.bridgecrew.io/docs"
|
||||
"NativeIaC": "",
|
||||
# Other holds the other commands, scripts or code to remediate it, use "https://www.trendmicro.com/cloudoneconformity"
|
||||
"Other": "https://docs.bridgecrew.io/docs/public_8#aws-console",
|
||||
# Terraform holds the Terraform code to remediate it, use "https://docs.bridgecrew.io/docs"
|
||||
"Terraform": ""
|
||||
},
|
||||
# Recommendation holds the recommendation for this check with a description and a related URL
|
||||
"Recommendation": {
|
||||
"Text": "We recommend your EC2 AMIs are not publicly accessible, or generally available in the Community AMIs.",
|
||||
"Url": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/cancel-sharing-an-AMI.html"
|
||||
}
|
||||
},
|
||||
# Categories holds the category or categories where the check can be included, if applied
|
||||
"Categories": [
|
||||
"internet-exposed"
|
||||
],
|
||||
# DependsOn is not actively used for the moment but it will hold other
|
||||
# checks wich this check is dependant to
|
||||
"DependsOn": [],
|
||||
# RelatedTo is not actively used for the moment but it will hold other
|
||||
# checks wich this check is related to
|
||||
"RelatedTo": [],
|
||||
# Notes holds additional information not covered in this file
|
||||
"Notes": ""
|
||||
}
|
||||
```
|
||||
|
||||
### Remediation Code
|
||||
|
||||
For the Remediation Code we use the following knowledge base to fill it:
|
||||
|
||||
- Official documentation for the provider
|
||||
- https://docs.bridgecrew.io
|
||||
- https://www.trendmicro.com/cloudoneconformity
|
||||
- https://github.com/cloudmatos/matos/tree/master/remediations
|
||||
|
||||
### RelatedURL and Recommendation
|
||||
|
||||
The RelatedURL field must be filled with an URL from the provider's official documentation like https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/sharingamis-intro.html
|
||||
|
||||
Also, if not present you can use the Risk and Recommendation texts from the TrendMicro [CloudConformity](https://www.trendmicro.com/cloudoneconformity) guide.
|
||||
|
||||
|
||||
### Python Model
|
||||
The following is the Python model for the check's metadata model. We use the Pydantic's [BaseModel](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel) as the parent class.
|
||||
|
||||
As per August 5th 2023 the `Check_Metadata_Model` can be found [here](https://github.com/prowler-cloud/prowler/blob/master/prowler/lib/check/models.py#L34-L56).
|
||||
```python
|
||||
class Check_Metadata_Model(BaseModel):
|
||||
"""Check Metadata Model"""
|
||||
|
||||
Provider: str
|
||||
CheckID: str
|
||||
CheckTitle: str
|
||||
CheckType: list[str]
|
||||
ServiceName: str
|
||||
SubServiceName: str
|
||||
ResourceIdTemplate: str
|
||||
Severity: str
|
||||
ResourceType: str
|
||||
Description: str
|
||||
Risk: str
|
||||
RelatedUrl: str
|
||||
Remediation: Remediation
|
||||
Categories: list[str]
|
||||
DependsOn: list[str]
|
||||
RelatedTo: list[str]
|
||||
Notes: str
|
||||
# We set the compliance to None to
|
||||
# store the compliance later if supplied
|
||||
Compliance: list = None
|
||||
```
|
||||
8
docs/developer-guide/documentation.md
Normal file
@@ -0,0 +1,8 @@
|
||||
## Contribute with documentation
|
||||
|
||||
We use `mkdocs` to build this Prowler documentation site so you can easily contribute back with new docs or improving them.
|
||||
|
||||
1. Install `mkdocs` with your favorite package manager.
|
||||
2. Inside the `prowler` repository folder run `mkdocs serve` and point your browser to `http://localhost:8000` and you will see live changes to your local copy of this documentation site.
|
||||
3. Make all needed changes to docs or add new documents. To do so just edit existing md files inside `prowler/docs` and if you are adding a new section or file please make sure you add it to `mkdocs.yaml` file in the root folder of the Prowler repo.
|
||||
4. Once you are done with changes, please send a pull request to us for review and merge. Thank you in advance!
|
||||
3
docs/developer-guide/integration-testing.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Integration Tests
|
||||
|
||||
Coming soon ...
|
||||
3
docs/developer-guide/integrations.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Create a new integration
|
||||
|
||||
Coming soon ...
|
||||
47
docs/developer-guide/introduction.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Developer Guide
|
||||
|
||||
You can extend Prowler in many different ways, in most cases you will want to create your own checks and compliance security frameworks, here is where you can learn about how to get started with it. We also include how to create custom outputs, integrations and more.
|
||||
|
||||
## Get the code and install all dependencies
|
||||
|
||||
First of all, you need a version of Python 3.9 or higher and also pip installed to be able to install all dependencies required. Once that is satisfied go a head and clone the repo:
|
||||
|
||||
```
|
||||
git clone https://github.com/prowler-cloud/prowler
|
||||
cd prowler
|
||||
```
|
||||
For isolation and avoid conflicts with other environments, we recommend usage of `poetry`:
|
||||
```
|
||||
pip install poetry
|
||||
```
|
||||
Then install all dependencies including the ones for developers:
|
||||
```
|
||||
poetry install
|
||||
poetry shell
|
||||
```
|
||||
|
||||
## Contributing with your code or fixes to Prowler
|
||||
|
||||
This repo has git pre-commit hooks managed via the [pre-commit](https://pre-commit.com/) tool. [Install](https://pre-commit.com/#install) it how ever you like, then in the root of this repo run:
|
||||
```shell
|
||||
pre-commit install
|
||||
```
|
||||
You should get an output like the following:
|
||||
```shell
|
||||
pre-commit installed at .git/hooks/pre-commit
|
||||
```
|
||||
|
||||
Before we merge any of your pull requests we pass checks to the code, we use the following tools and automation to make sure the code is secure and dependencies up-to-dated (these should have been already installed if you ran `pipenv install -d`):
|
||||
|
||||
- [`bandit`](https://pypi.org/project/bandit/) for code security review.
|
||||
- [`safety`](https://pypi.org/project/safety/) and [`dependabot`](https://github.com/features/security) for dependencies.
|
||||
- [`hadolint`](https://github.com/hadolint/hadolint) and [`dockle`](https://github.com/goodwithtech/dockle) for our containers security.
|
||||
- [`Snyk`](https://docs.snyk.io/integrations/snyk-container-integrations/container-security-with-docker-hub-integration) in Docker Hub.
|
||||
- [`clair`](https://github.com/quay/clair) in Amazon ECR.
|
||||
- [`vulture`](https://pypi.org/project/vulture/), [`flake8`](https://pypi.org/project/flake8/), [`black`](https://pypi.org/project/black/) and [`pylint`](https://pypi.org/project/pylint/) for formatting and best practices.
|
||||
|
||||
You can see all dependencies in file `pyproject.toml`.
|
||||
|
||||
## Want some swag as appreciation for your contribution?
|
||||
|
||||
If you are like us and you love swag, we are happy to thank you for your contribution with some laptop stickers or whatever other swag we may have at that time. Please, tell us more details and your pull request link in our [Slack workspace here](https://join.slack.com/t/prowler-workspace/shared_invite/zt-1hix76xsl-2uq222JIXrC7Q8It~9ZNog). You can also reach out to Toni de la Fuente on Twitter [here](https://twitter.com/ToniBlyx), his DMs are open.
|
||||
3
docs/developer-guide/outputs.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Create a custom output format
|
||||
|
||||
Coming soon ...
|
||||
41
docs/developer-guide/security-compliance-framework.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Create a new security compliance framework
|
||||
|
||||
|
||||
## Introduction
|
||||
If you want to create or contribute with your own security frameworks or add public ones to Prowler you need to make sure the checks are available if not you have to create your own. Then create a compliance file per provider like in `prowler/compliance/<provider>/` and name it as `<framework>_<version>_<provider>.json` then follow the following format to create yours.
|
||||
|
||||
## Compliance Framework
|
||||
Each file version of a framework will have the following structure at high level with the case that each framework needs to be generally identified, one requirement can be also called one control but one requirement can be linked to multiple prowler checks.:
|
||||
|
||||
- `Framework`: string. Distinguish name of the framework, like CIS
|
||||
- `Provider`: string. Provider where the framework applies, such as AWS, Azure, OCI,...
|
||||
- `Version`: string. Version of the framework itself, like 1.4 for CIS.
|
||||
- `Requirements`: array of objects. Include all requirements or controls with the mapping to Prowler.
|
||||
- `Requirements_Id`: string. Unique identifier per each requirement in the specific framework
|
||||
- `Requirements_Description`: string. Description as in the framework.
|
||||
- `Requirements_Attributes`: array of objects. Includes all needed attributes per each requirement, like levels, sections, etc. Whatever helps to create a dedicated report with the result of the findings. Attributes would be taken as closely as possible from the framework's own terminology directly.
|
||||
- `Requirements_Checks`: array. Prowler checks that are needed to prove this requirement. It can be one or multiple checks. In case of no automation possible this can be empty.
|
||||
|
||||
```
|
||||
{
|
||||
"Framework": "<framework>-<provider>",
|
||||
"Version": "<version>",
|
||||
"Requirements": [
|
||||
{
|
||||
"Id": "<unique-id>",
|
||||
"Description": "Requiemente full description",
|
||||
"Checks": [
|
||||
"Here is the prowler check or checks that is going to be executed"
|
||||
],
|
||||
"Attributes": [
|
||||
{
|
||||
<Add here your custom attributes.>
|
||||
}
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Finally, to have a proper output file for your reports, your framework data model has to be created in `prowler/lib/outputs/models.py` and also the CLI table output in `prowler/lib/outputs/compliance.py`.
|
||||
235
docs/developer-guide/services.md
Normal file
@@ -0,0 +1,235 @@
|
||||
# Create a new Provider Service
|
||||
|
||||
Here you can find how to create a new service, or to complement an existing one, for a Prowler Provider.
|
||||
|
||||
## Introduction
|
||||
|
||||
To create a new service, you will need to create a folder inside the specific provider, i.e. `prowler/providers/<provider>/services/<service>/`.
|
||||
|
||||
Inside that folder, you MUST create the following files:
|
||||
|
||||
- An empty `__init__.py`: to make Python treat this service folder as a package.
|
||||
- A `<service>_service.py`, containing all the service's logic and API calls.
|
||||
- A `<service>_client_.py`, containing the initialization of the service's class we have just created so the checks's checks can use it.
|
||||
|
||||
## Service
|
||||
|
||||
The Prowler's service structure is the following and the way to initialise it is just by importing the service client in a check.
|
||||
|
||||
## Service Base Class
|
||||
|
||||
All the Prowler provider's services inherits from a base class depending on the provider used.
|
||||
|
||||
- [AWS Service Base Class](https://github.com/prowler-cloud/prowler/blob/22f8855ad7dad2e976dabff78611b643e234beaf/prowler/providers/aws/lib/service/service.py)
|
||||
- [GCP Service Base Class](https://github.com/prowler-cloud/prowler/blob/22f8855ad7dad2e976dabff78611b643e234beaf/prowler/providers/gcp/lib/service/service.py)
|
||||
- [Azure Service Base Class](https://github.com/prowler-cloud/prowler/blob/22f8855ad7dad2e976dabff78611b643e234beaf/prowler/providers/azure/lib/service/service.py)
|
||||
|
||||
Each class is used to initialize the credentials and the API's clients to be used in the service. If some threading is used it must be coded there.
|
||||
|
||||
## Service Class
|
||||
|
||||
Due to the complexity and differencies of each provider API we are going to use an example service to guide you in how can it be created.
|
||||
|
||||
The following is the `<service>_service.py` file:
|
||||
|
||||
```python title="Service Class"
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
# The following is just for the AWS provider
|
||||
from botocore.client import ClientError
|
||||
|
||||
# To use the Pydantic's BaseModel
|
||||
from pydantic import BaseModel
|
||||
|
||||
# Prowler logging library
|
||||
from prowler.lib.logger import logger
|
||||
|
||||
# Prowler resource filter, only for the AWS provider
|
||||
from prowler.lib.scan_filters.scan_filters import is_resource_filtered
|
||||
|
||||
# Provider parent class
|
||||
from prowler.providers.<provider>.lib.service.service import ServiceParentClass
|
||||
|
||||
|
||||
# Create a class for the Service
|
||||
################## <Service>
|
||||
class <Service>(ServiceParentClass):
|
||||
def __init__(self, audit_info):
|
||||
# Call Service Parent Class __init__
|
||||
# We use the __class__.__name__ to get it automatically
|
||||
# from the Service Class name but you can pass a custom
|
||||
# string if the provider's API service name is different
|
||||
super().__init__(__class__.__name__, audit_info)
|
||||
|
||||
# Create an empty dictionary of items to be gathered,
|
||||
# using the unique ID as the dictionary key
|
||||
# e.g., instances
|
||||
self.<items> = {}
|
||||
|
||||
# If you can parallelize by regions or locations
|
||||
# you can use the __threading_call__ function
|
||||
# available in the Service Parent Class
|
||||
self.__threading_call__(self.__describe_<items>__)
|
||||
|
||||
# Optionally you can create another function to retrieve
|
||||
# more data about each item without parallel
|
||||
self.__describe_<item>__()
|
||||
|
||||
def __describe_<items>__(self, regional_client):
|
||||
"""Get ALL <Service> <Items>"""
|
||||
logger.info("<Service> - Describing <Items>...")
|
||||
|
||||
# We MUST include a try/except block in each function
|
||||
try:
|
||||
|
||||
# Call to the provider API to retrieve the data we want
|
||||
describe_<items>_paginator = regional_client.get_paginator("describe_<items>")
|
||||
|
||||
# Paginator to get every item
|
||||
for page in describe_<items>_paginator.paginate():
|
||||
|
||||
# Another try/except within the loop for to continue looping
|
||||
# if something unexpected happens
|
||||
try:
|
||||
|
||||
for <item> in page["<Items>"]:
|
||||
|
||||
# For the AWS provider we MUST include the following lines to retrieve
|
||||
# or not data for the resource passed as argument using the --resource-arn
|
||||
if not self.audit_resources or (
|
||||
is_resource_filtered(<item>["<item_arn>"], self.audit_resources)
|
||||
):
|
||||
# Then we have to include the retrieved resource in the object
|
||||
# previously created
|
||||
self.<items>[<item_unique_id>] =
|
||||
<Item>(
|
||||
arn=stack["<item_arn>"],
|
||||
name=stack["<item_name>"],
|
||||
tags=stack.get("Tags", []),
|
||||
region=regional_client.region,
|
||||
)
|
||||
|
||||
except Exception as error:
|
||||
logger.error(
|
||||
f"{<provider_specific_field>} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
|
||||
# In the except part we have to use the following code to log the errors
|
||||
except Exception as error:
|
||||
# Depending on each provider we can use the following fields in the logger:
|
||||
# - AWS: regional_client.region or self.region
|
||||
# - GCP: project_id and location
|
||||
# - Azure: subscription
|
||||
|
||||
logger.error(
|
||||
f"{<provider_specific_field>} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
|
||||
def __describe_<item>__(self):
|
||||
"""Get Details for a <Service> <Item>"""
|
||||
logger.info("<Service> - Describing <Item> to get specific details...")
|
||||
|
||||
# We MUST include a try/except block in each function
|
||||
try:
|
||||
|
||||
# Loop over the items retrieved in the previous function
|
||||
for <item> in self.<items>:
|
||||
|
||||
# When we perform calls to the Provider API within a for loop we have
|
||||
# to include another try/except block because in the cloud there are
|
||||
# ephemeral resources that can be deleted at the time we are checking them
|
||||
try:
|
||||
<item>_details = self.regional_clients[<item>.region].describe_<item>(
|
||||
<Attribute>=<item>.name
|
||||
)
|
||||
|
||||
# For example, check if item is Public. Here is important if we are
|
||||
# getting values from a dictionary we have to use the "dict.get()"
|
||||
# function with a default value in the case this value is not present
|
||||
<item>.public = <item>_details.get("Public", False)
|
||||
|
||||
|
||||
# In this except block, for example for the AWS Provider we can use
|
||||
# the botocore.ClientError exception and check for a specific error code
|
||||
# to raise a WARNING instead of an ERROR if some resource is not present.
|
||||
except ClientError as error:
|
||||
if error.response["Error"]["Code"] == "InvalidInstanceID.NotFound":
|
||||
logger.warning(
|
||||
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
else:
|
||||
logger.error(
|
||||
f"{<provider_specific_field>} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
continue
|
||||
|
||||
# In the except part we have to use the following code to log the errors
|
||||
except Exception as error:
|
||||
# Depending on each provider we can use the following fields in the logger:
|
||||
# - AWS: regional_client.region or self.region
|
||||
# - GCP: project_id and location
|
||||
# - Azure: subscription
|
||||
|
||||
logger.error(
|
||||
f"{<item>.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
```
|
||||
|
||||
### Service Models
|
||||
|
||||
For each class object we need to model we use the Pydantic's [BaseModel](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel) to take advantage of the data validation.
|
||||
|
||||
```python title="Service Model"
|
||||
# In each service class we have to create some classes using
|
||||
# the Pydantic's Basemodel for the resources we want to audit.
|
||||
class <Item>(BaseModel):
|
||||
"""<Item> holds a <Service> <Item>"""
|
||||
|
||||
arn: str
|
||||
"""<Items>[].arn"""
|
||||
|
||||
name: str
|
||||
"""<Items>[].name"""
|
||||
|
||||
region: str
|
||||
"""<Items>[].region"""
|
||||
|
||||
public: bool
|
||||
"""<Items>[].public"""
|
||||
|
||||
# We can create Optional attributes set to None by default
|
||||
tags: Optional[list]
|
||||
"""<Items>[].tags"""
|
||||
```
|
||||
### Service Objects
|
||||
In the service each group of resources should be created as a Python [dictionary](https://docs.python.org/3/tutorial/datastructures.html#dictionaries). This is because we are performing lookups all the time and the Python dictionary lookup has [O(1) complexity](https://en.wikipedia.org/wiki/Big_O_notation#Orders_of_common_functions).
|
||||
|
||||
We MUST set as the dictionary key a unique ID, like the resource Unique ID or ARN.
|
||||
|
||||
Example:
|
||||
```python
|
||||
self.vpcs = {}
|
||||
self.vpcs["vpc-01234567890abcdef"] = VPC_Object_Class()
|
||||
```
|
||||
|
||||
## Service Client
|
||||
|
||||
Each Prowler service requires a service client to use the service in the checks.
|
||||
|
||||
The following is the `<service>_client.py` containing the initialization of the service's class we have just created so the service's checks can use them:
|
||||
|
||||
```python
|
||||
from prowler.providers.<provider>.lib.audit_info.audit_info import audit_info
|
||||
from prowler.providers.<provider>.services.<service>.<service>_service import <Service>
|
||||
|
||||
<service>_client = <Service>(audit_info)
|
||||
```
|
||||
|
||||
## Permissions
|
||||
|
||||
It is really important to check if the current Prowler's permissions for each provider are enough to implement a new service. If we need to include more please refer to the following documentaion and update it:
|
||||
|
||||
- AWS: https://docs.prowler.cloud/en/latest/getting-started/requirements/#aws-authentication
|
||||
- Azure: https://docs.prowler.cloud/en/latest/getting-started/requirements/#permissions
|
||||
- GCP: https://docs.prowler.cloud/en/latest/getting-started/requirements/#gcp-authentication
|
||||
590
docs/developer-guide/unit-testing.md
Normal file
@@ -0,0 +1,590 @@
|
||||
# Unit Tests
|
||||
|
||||
The unit tests for the Prowler checks varies between each provider supported.
|
||||
|
||||
Here we left some good reads about unit testing and things we've learnt through all the process.
|
||||
|
||||
**Python Testing**
|
||||
|
||||
- https://docs.python-guide.org/writing/tests/
|
||||
|
||||
**Where to patch**
|
||||
|
||||
- https://docs.python.org/3/library/unittest.mock.html#where-to-patch
|
||||
- https://stackoverflow.com/questions/893333/multiple-variables-in-a-with-statement
|
||||
- https://docs.python.org/3/reference/compound_stmts.html#the-with-statement
|
||||
|
||||
**Utils to trace mocking and test execution**
|
||||
|
||||
- https://news.ycombinator.com/item?id=36054868
|
||||
- https://docs.python.org/3/library/sys.html#sys.settrace
|
||||
- https://github.com/kunalb/panopticon
|
||||
|
||||
## General Recommendations
|
||||
|
||||
When creating tests for some provider's checks we follow these guidelines trying to cover as much test scenarios as possible:
|
||||
|
||||
1. Create a test without resource to generate 0 findings, because Prowler will generate 0 findings if a service does not contain the resources the check is looking for audit.
|
||||
2. Create test to generate both a `PASS` and a `FAIL` result.
|
||||
3. Create tests with more than 1 resource to evaluate how the check behaves and if the number of findings is right.
|
||||
|
||||
## How to run Prowler tests
|
||||
|
||||
To run the Prowler test suite you need to install the testing dependencies already included in the `pyproject.toml` file. If you didn't install it yet please read the developer guide introduction [here](./introduction.md#get-the-code-and-install-all-dependencies).
|
||||
|
||||
Then in the project's root path execute `pytest -n auto -vvv -s -x` or use the `Makefile` with `make test`.
|
||||
|
||||
Other commands to run tests:
|
||||
|
||||
- Run tests for a provider: `pytest -n auto -vvv -s -x tests/providers/<provider>/services`
|
||||
- Run tests for a provider service: `pytest -n auto -vvv -s -x tests/providers/<provider>/services/<service>`
|
||||
- Run tests for a provider check: `pytest -n auto -vvv -s -x tests/providers/<provider>/services/<service>/<check>`
|
||||
|
||||
> Refer to the [pytest documentation](https://docs.pytest.org/en/7.1.x/getting-started.html) documentation for more information.
|
||||
|
||||
## AWS
|
||||
|
||||
For the AWS provider we have ways to test a Prowler check based on the following criteria:
|
||||
|
||||
> Note: We use and contribute to the [Moto](https://github.com/getmoto/moto) library which allows us to easily mock out tests based on AWS infrastructure. **It's awesome!**
|
||||
|
||||
- AWS API calls covered by [Moto](https://github.com/getmoto/moto):
|
||||
- Service tests with `@mock_<service>`
|
||||
- Checks tests with `@mock_<service>`
|
||||
- AWS API calls not covered by Moto:
|
||||
- Service test with `mock_make_api_call`
|
||||
- Checks tests with [MagicMock](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.MagicMock)
|
||||
- AWS API calls partially covered by Moto:
|
||||
- Service test with `@mock_<service>` and `mock_make_api_call`
|
||||
- Checks tests with `@mock_<service>` and `mock_make_api_call`
|
||||
|
||||
In the following section we are going to explain all of the above scenarios with examples based on if the [Moto](https://github.com/getmoto/moto) library covers the AWS API calls made by the service. You can check the covered API calls [here](https://github.com/getmoto/moto/blob/master/IMPLEMENTATION_COVERAGE.md).
|
||||
|
||||
An important point for the AWS testing is that in each check we MUST have a unique `audit_info` which is the key object during the AWS execution to isolate the test execution.
|
||||
|
||||
Check the [Audit Info](./audit-info.md) section to get more details.
|
||||
|
||||
```python
|
||||
# We need to import the AWS_Audit_Info and the Audit_Metadata
|
||||
# to set the audit_info to call AWS APIs
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from prowler.providers.common.models import Audit_Metadata
|
||||
|
||||
AWS_ACCOUNT_NUMBER = "123456789012"
|
||||
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
session_config=None,
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audit_config=None,
|
||||
audited_account=AWS_ACCOUNT_NUMBER,
|
||||
audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root",
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=["us-east-1", "eu-west-1"],
|
||||
organizations_metadata=None,
|
||||
audit_resources=None,
|
||||
mfa_enabled=False,
|
||||
audit_metadata=Audit_Metadata(
|
||||
services_scanned=0,
|
||||
expected_checks=[],
|
||||
completed_checks=0,
|
||||
audit_progress=0,
|
||||
),
|
||||
)
|
||||
|
||||
return audit_info
|
||||
```
|
||||
### Checks
|
||||
|
||||
For the AWS tests examples we are going to use the tests for the `iam_password_policy_uppercase` check.
|
||||
|
||||
This section is going to be divided based on the API coverage of the [Moto](https://github.com/getmoto/moto) library.
|
||||
|
||||
#### API calls covered
|
||||
|
||||
If the [Moto](https://github.com/getmoto/moto) library covers the API calls we want to test we can use the `@mock_<service>` decorator which will mocked out all the API calls made to AWS keeping the state within the code decorated, in this case the test function.
|
||||
|
||||
```python
|
||||
# We need to import the unittest.mock to allow us to patch some objects
|
||||
# not to use shared ones between test, hence to isolate the test
|
||||
from unittest import mock
|
||||
|
||||
# Boto3 client and session to call the AWS APIs
|
||||
from boto3 import client, session
|
||||
|
||||
# Moto decorator for the IAM service we want to mock
|
||||
from moto import mock_iam
|
||||
|
||||
# Constants used
|
||||
AWS_ACCOUNT_NUMBER = "123456789012"
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
# We always name the test classes like Test_<check_name>
|
||||
class Test_iam_password_policy_uppercase:
|
||||
|
||||
# We include the Moto decorator for the service we want to use
|
||||
# You can include more than one if two or more services are
|
||||
# involved in test
|
||||
@mock_iam
|
||||
# We name the tests with test_<service>_<check_name>_<test_action>
|
||||
def test_iam_password_policy_no_uppercase_flag(self):
|
||||
# First, we have to create an IAM client
|
||||
iam_client = client("iam", region_name=AWS_REGION)
|
||||
|
||||
# Then, since all the AWS accounts have a password
|
||||
# policy we want to set to False the RequireUppercaseCharacters
|
||||
iam_client.update_account_password_policy(RequireUppercaseCharacters=False)
|
||||
|
||||
# We set a mocked audit_info for AWS not to share the same audit state
|
||||
# between checks
|
||||
current_audit_info = self.set_mocked_audit_info()
|
||||
|
||||
# The Prowler service import MUST be made within the decorated
|
||||
# code not to make real API calls to the AWS service.
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
# Prowler for AWS uses a shared object called `current_audit_info` where it stores
|
||||
# the audit's state, credentials and configuration.
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
new=current_audit_info,
|
||||
),
|
||||
# We have to mock also the iam_client from the check to enforce that the iam_client used is the one
|
||||
# created within this check because patch != import, and if you execute tests in parallel some objects
|
||||
# can be already initialised hence the check won't be isolated
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_password_policy_uppercase.iam_password_policy_uppercase.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# We import the check within the two mocks not to initialise the iam_client with some shared information from
|
||||
# the current_audit_info or the IAM service.
|
||||
from prowler.providers.aws.services.iam.iam_password_policy_uppercase.iam_password_policy_uppercase import (
|
||||
iam_password_policy_uppercase,
|
||||
)
|
||||
|
||||
# Once imported, we only need to instantiate the check's class
|
||||
check = iam_password_policy_uppercase()
|
||||
|
||||
# And then, call the execute() function to run the check
|
||||
# against the IAM client we've set up.
|
||||
result = check.execute()
|
||||
|
||||
# Last but not least, we need to assert all the fields
|
||||
# from the check's results
|
||||
assert len(results) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status_extended == "IAM password policy does not require at least one uppercase letter."
|
||||
assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
|
||||
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
|
||||
assert result[0].resource_tags == []
|
||||
assert result[0].region == AWS_REGION
|
||||
```
|
||||
|
||||
#### API calls not covered
|
||||
|
||||
If the IAM service for the check's we want to test is not covered by Moto we have to inject the objects in the service client using [MagicMock](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.MagicMock) because we cannot instantiate the service since it will make real calls to the AWS APIs.
|
||||
|
||||
> The following example uses the IAM GetAccountPasswordPolicy which is covered by Moto but this is only for demonstration purposes.
|
||||
|
||||
The following code shows how to use MagicMock to create the service objects.
|
||||
|
||||
```python
|
||||
# We need to import the unittest.mock to allow us to patch some objects
|
||||
# not to use shared ones between test, hence to isolate the test
|
||||
from unittest import mock
|
||||
|
||||
# Constants used
|
||||
AWS_ACCOUNT_NUMBER = "123456789012"
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
# We always name the test classes like Test_<check_name>
|
||||
class Test_iam_password_policy_uppercase:
|
||||
|
||||
# We name the tests with test_<service>_<check_name>_<test_action>
|
||||
def test_iam_password_policy_no_uppercase_flag(self):
|
||||
# Mocked client with MagicMock
|
||||
mocked_iam_client = mock.MagicMock
|
||||
|
||||
# Since the IAM Password Policy has their own model we have to import it
|
||||
from prowler.providers.aws.services.iam.iam_service import PasswordPolicy
|
||||
|
||||
# Create the mock PasswordPolicy object
|
||||
mocked_iam_client.password_policy = PasswordPolicy(
|
||||
length=5,
|
||||
symbols=True,
|
||||
numbers=True,
|
||||
# We set the value to False to test the check
|
||||
uppercase=False,
|
||||
lowercase=True,
|
||||
allow_change=False,
|
||||
expiration=True,
|
||||
)
|
||||
|
||||
# We set a mocked audit_info for AWS not to share the same audit state
|
||||
# between checks
|
||||
current_audit_info = self.set_mocked_audit_info()
|
||||
|
||||
# In this scenario we have to mock also the IAM service and the iam_client from the check to enforce that the iam_client used is the one created within this check because patch != import, and if you execute tests in parallel some objects can be already initialised hence the check won't be isolated.
|
||||
# In this case we don't use the Moto decorator, we use the mocked IAM client for both objects
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_service.IAM",
|
||||
new=mocked_iam_client,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_client.iam_client",
|
||||
new=mocked_iam_client,
|
||||
):
|
||||
# We import the check within the two mocks not to initialise the iam_client with some shared information from
|
||||
# the current_audit_info or the IAM service.
|
||||
from prowler.providers.aws.services.iam.iam_password_policy_uppercase.iam_password_policy_uppercase import (
|
||||
iam_password_policy_uppercase,
|
||||
)
|
||||
|
||||
# Once imported, we only need to instantiate the check's class
|
||||
check = iam_password_policy_uppercase()
|
||||
|
||||
# And then, call the execute() function to run the check
|
||||
# against the IAM client we've set up.
|
||||
result = check.execute()
|
||||
|
||||
# Last but not least, we need to assert all the fields
|
||||
# from the check's results
|
||||
assert len(results) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status_extended == "IAM password policy does not require at least one uppercase letter."
|
||||
assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
|
||||
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
|
||||
assert result[0].resource_tags == []
|
||||
assert result[0].region == AWS_REGION
|
||||
```
|
||||
|
||||
#### API calls partially covered
|
||||
|
||||
If the API calls we want to use in the service are partially covered by the Moto decorator we have to create our own mocked API calls to use it in combination.
|
||||
|
||||
To do so, you need to mock the `botocore.client.BaseClient._make_api_call` function, which is the Boto3 function in charge of making the real API call to the AWS APIs, using `mock.patch <https://docs.python.org/3/library/unittest.mock.html#patch>`:
|
||||
|
||||
|
||||
```python
|
||||
|
||||
import boto3
|
||||
import botocore
|
||||
from unittest.mock import patch
|
||||
from moto import mock_iam
|
||||
|
||||
# Original botocore _make_api_call function
|
||||
orig = botocore.client.BaseClient._make_api_call
|
||||
|
||||
# Mocked botocore _make_api_call function
|
||||
def mock_make_api_call(self, operation_name, kwarg):
|
||||
# As you can see the operation_name has the get_account_password_policy snake_case form but
|
||||
# we are using the GetAccountPasswordPolicy form.
|
||||
# Rationale -> https://github.com/boto/botocore/blob/develop/botocore/client.py#L810:L816
|
||||
if operation_name == 'GetAccountPasswordPolicy':
|
||||
return {
|
||||
'PasswordPolicy': {
|
||||
'MinimumPasswordLength': 123,
|
||||
'RequireSymbols': True|False,
|
||||
'RequireNumbers': True|False,
|
||||
'RequireUppercaseCharacters': True|False,
|
||||
'RequireLowercaseCharacters': True|False,
|
||||
'AllowUsersToChangePassword': True|False,
|
||||
'ExpirePasswords': True|False,
|
||||
'MaxPasswordAge': 123,
|
||||
'PasswordReusePrevention': 123,
|
||||
'HardExpiry': True|False
|
||||
}
|
||||
}
|
||||
# If we don't want to patch the API call
|
||||
return orig(self, operation_name, kwarg)
|
||||
|
||||
# We always name the test classes like Test_<check_name>
|
||||
class Test_iam_password_policy_uppercase:
|
||||
|
||||
# We include the custom API call mock decorator for the service we want to use
|
||||
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
|
||||
# We include also the IAM Moto decorator for the API calls supported
|
||||
@mock_iam
|
||||
# We name the tests with test_<service>_<check_name>_<test_action>
|
||||
def test_iam_password_policy_no_uppercase_flag(self):
|
||||
# Check the previous section to see the check test since is the same
|
||||
```
|
||||
|
||||
Note that this does not use Moto, to keep it simple, but if you use any `moto`-decorators in addition to the patch, the call to `orig(self, operation_name, kwarg)` will be intercepted by Moto.
|
||||
|
||||
> The above code comes from here https://docs.getmoto.org/en/latest/docs/services/patching_other_services.html
|
||||
|
||||
#### Mocking more than one service
|
||||
|
||||
If the test your are creating belongs to a check that uses more than one provider service, you should mock each of the services used. For example, the check `cloudtrail_logs_s3_bucket_access_logging_enabled` requires the CloudTrail and the S3 client, hence the service's mock part of the test will be as follows:
|
||||
|
||||
|
||||
```python
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
new=mock_audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(mock_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_logs_s3_bucket_access_logging_enabled.s3_client",
|
||||
new=S3(mock_audit_info),
|
||||
):
|
||||
```
|
||||
|
||||
|
||||
As you can see in the above code, it is required to mock the AWS audit info and both services used.
|
||||
|
||||
|
||||
#### Patching vs. Importing
|
||||
|
||||
This is an important topic within the Prowler check's unit testing. Due to the dynamic nature of the check's load, the process of importing the service client from a check is the following:
|
||||
|
||||
1. `<check>.py`:
|
||||
```python
|
||||
from prowler.providers.<provider>.services.<service>.<service>_client import <service>_client
|
||||
```
|
||||
2. `<service>_client.py`:
|
||||
```python
|
||||
from prowler.providers.<provider>.lib.audit_info.audit_info import audit_info
|
||||
from prowler.providers.<provider>.services.<service>.<service>_service import <SERVICE>
|
||||
|
||||
<service>_client = <SERVICE>(audit_info)
|
||||
```
|
||||
|
||||
Due to the above import path it's not the same to patch the following objects because if you run a bunch of tests, either in parallel or not, some clients can be already instantiated by another check, hence your test exection will be using another test's service instance:
|
||||
|
||||
- `<service>_client` imported at `<check>.py`
|
||||
- `<service>_client` initialised at `<service>_client.py`
|
||||
- `<SERVICE>` imported at `<service>_client.py`
|
||||
|
||||
A useful read about this topic can be found in the following article: https://stackoverflow.com/questions/8658043/how-to-mock-an-import
|
||||
|
||||
|
||||
#### Different ways to mock the service client
|
||||
|
||||
##### Mocking the service client at the service client level
|
||||
|
||||
Mocking a service client using the following code ...
|
||||
|
||||
```python title="Mocking the service_client"
|
||||
with mock.patch(
|
||||
"prowler.providers.<provider>.lib.audit_info.audit_info.audit_info",
|
||||
new=audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.<service>.<check>.<check>.<service>_client",
|
||||
new=<SERVICE>(audit_info),
|
||||
):
|
||||
```
|
||||
will cause that the service will be initialised twice:
|
||||
|
||||
1. When the `<SERVICE>(audit_info)` is mocked out using `mock.patch` to have the object ready for the patching.
|
||||
2. At the `<service>_client.py` when we are patching it since the `mock.patch` needs to go to that object an initialise it, hence the `<SERVICE>(audit_info)` will be called again.
|
||||
|
||||
Then, when we import the `<service>_client.py` at `<check>.py`, since we are mocking where the object is used, Python will use the mocked one.
|
||||
|
||||
In the [next section](./unit-testing.md#mocking-the-service-and-the-service-client-at-the-service-client-level) you will see an improved version to mock objects.
|
||||
|
||||
|
||||
##### Mocking the service and the service client at the service client level
|
||||
Mocking a service client using the following code ...
|
||||
|
||||
```python title="Mocking the service and the service_client"
|
||||
with mock.patch(
|
||||
"prowler.providers.<provider>.lib.audit_info.audit_info.audit_info",
|
||||
new=audit_info,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.<service>.<SERVICE>",
|
||||
return_value=<SERVICE>(audit_info),
|
||||
) as service_client, mock.patch(
|
||||
"prowler.providers.aws.services.<service>.<service>_client.<service>_client",
|
||||
new=service_client,
|
||||
):
|
||||
```
|
||||
will cause that the service will be initialised once, just when the `<SERVICE>(audit_info)` is mocked out using `mock.patch`.
|
||||
|
||||
Then, at the check_level when Python tries to import the client with `from prowler.providers.<provider>.services.<service>.<service>_client`, since it is already mocked out, the execution will continue using the `service_client` without getting into the `<service>_client.py`.
|
||||
|
||||
|
||||
### Services
|
||||
|
||||
For testing the AWS services we have to follow the same logic as with the AWS checks, we have to check if the AWS API calls made by the service are covered by Moto and we have to test the service `__init__` to verifiy that the information is being correctly retrieved.
|
||||
|
||||
The service tests could act as *Integration Tests* since we test how the service retrieves the information from the provider, but since Moto or the custom mock objects mocks that calls this test will fall into *Unit Tests*.
|
||||
|
||||
Please refer to the [AWS checks tests](./unit-testing.md#checks) for more information on how to create tests and check the existing services tests [here](https://github.com/prowler-cloud/prowler/tree/master/tests/providers/aws/services).
|
||||
|
||||
## GCP
|
||||
|
||||
### Checks
|
||||
|
||||
For the GCP Provider we don't have any library to mock out the API calls we use. So in this scenario we inject the objects in the service client using [MagicMock](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.MagicMock).
|
||||
|
||||
The following code shows how to use MagicMock to create the service objects for a GCP check test.
|
||||
|
||||
```python
|
||||
# We need to import the unittest.mock to allow us to patch some objects
|
||||
# not to use shared ones between test, hence to isolate the test
|
||||
from unittest import mock
|
||||
|
||||
# GCP Constants
|
||||
GCP_PROJECT_ID = "123456789012"
|
||||
|
||||
# We are going to create a test for the compute_firewall_rdp_access_from_the_internet_allowed check
|
||||
class Test_compute_firewall_rdp_access_from_the_internet_allowed:
|
||||
|
||||
# We name the tests with test_<service>_<check_name>_<test_action>
|
||||
def test_compute_compute_firewall_rdp_access_from_the_internet_allowed_one_compliant_rule_with_valid_port(self):
|
||||
# Mocked client with MagicMock
|
||||
compute_client = mock.MagicMock
|
||||
|
||||
# Assign GCP client configuration
|
||||
compute_client.project_ids = [GCP_PROJECT_ID]
|
||||
compute_client.region = "global"
|
||||
|
||||
# Import the service resource model to create the mocked object
|
||||
from prowler.providers.gcp.services.compute.compute_service import Firewall
|
||||
|
||||
# Create the custom Firewall object to be tested
|
||||
firewall = Firewall(
|
||||
name="test",
|
||||
id="1234567890",
|
||||
source_ranges=["0.0.0.0/0"],
|
||||
direction="INGRESS",
|
||||
allowed_rules=[{"IPProtocol": "tcp", "ports": ["443"]}],
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
compute_client.firewalls = [firewall]
|
||||
|
||||
# In this scenario we have to mock also the Compute service and the compute_client from the check to enforce that the compute_client used is the one created within this check because patch != import, and if you execute tests in parallel some objects can be already initialised hence the check won't be isolated.
|
||||
# In this case we don't use the Moto decorator, we use the mocked Compute client for both objects
|
||||
with mock.patch(
|
||||
"prowler.providers.gcp.services.compute.compute_service.Compute",
|
||||
new=defender_client,
|
||||
), mock.patch(
|
||||
"prowler.providers.gcp.services.compute.compute_client.compute_client",
|
||||
new=defender_client,
|
||||
):
|
||||
|
||||
# We import the check within the two mocks not to initialise the iam_client with some shared information from
|
||||
# the current_audit_info or the Compute service.
|
||||
from prowler.providers.gcp.services.compute.compute_firewall_rdp_access_from_the_internet_allowed.compute_firewall_rdp_access_from_the_internet_allowed import (
|
||||
compute_firewall_rdp_access_from_the_internet_allowed,
|
||||
)
|
||||
|
||||
# Once imported, we only need to instantiate the check's class
|
||||
check = compute_firewall_rdp_access_from_the_internet_allowed()
|
||||
|
||||
# And then, call the execute() function to run the check
|
||||
# against the IAM client we've set up.
|
||||
result = check.execute()
|
||||
|
||||
# Last but not least, we need to assert all the fields
|
||||
# from the check's results
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == f"Firewall {firewall.name} does not expose port 3389 (RDP) to the internet."
|
||||
assert result[0].resource_name = firewall.name
|
||||
assert result[0].resource_id == firewall.id
|
||||
assert result[0].project_id = GCP_PROJECT_ID
|
||||
assert result[0].location = compute_client.region
|
||||
```
|
||||
|
||||
### Services
|
||||
|
||||
Coming soon ...
|
||||
|
||||
## Azure
|
||||
|
||||
### Checks
|
||||
|
||||
For the Azure Provider we don't have any library to mock out the API calls we use. So in this scenario we inject the objects in the service client using [MagicMock](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.MagicMock).
|
||||
|
||||
The following code shows how to use MagicMock to create the service objects for a Azure check test.
|
||||
|
||||
```python
|
||||
# We need to import the unittest.mock to allow us to patch some objects
|
||||
# not to use shared ones between test, hence to isolate the test
|
||||
from unittest import mock
|
||||
|
||||
from uuid import uuid4
|
||||
|
||||
# Azure Constants
|
||||
AZURE_SUSCRIPTION = str(uuid4())
|
||||
|
||||
|
||||
|
||||
# We are going to create a test for the Test_defender_ensure_defender_for_arm_is_on check
|
||||
class Test_defender_ensure_defender_for_arm_is_on:
|
||||
|
||||
# We name the tests with test_<service>_<check_name>_<test_action>
|
||||
def test_defender_defender_ensure_defender_for_arm_is_on_arm_pricing_tier_not_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
|
||||
# Mocked client with MagicMock
|
||||
defender_client = mock.MagicMock
|
||||
|
||||
# Import the service resource model to create the mocked object
|
||||
from prowler.providers.azure.services.defender.defender_service import Defender_Pricing
|
||||
|
||||
# Create the custom Defender object to be tested
|
||||
defender_client.pricings = {
|
||||
AZURE_SUSCRIPTION: {
|
||||
"Arm": Defender_Pricing(
|
||||
resource_id=resource_id,
|
||||
pricing_tier="Not Standard",
|
||||
free_trial_remaining_time=0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
# In this scenario we have to mock also the Defender service and the defender_client from the check to enforce that the defender_client used is the one created within this check because patch != import, and if you execute tests in parallel some objects can be already initialised hence the check won't be isolated.
|
||||
# In this case we don't use the Moto decorator, we use the mocked Defender client for both objects
|
||||
with mock.patch(
|
||||
"prowler.providers.azure.services.defender.defender_service.Defender",
|
||||
new=defender_client,
|
||||
), mock.patch(
|
||||
"prowler.providers.azure.services.defender.defender_client.defender_client",
|
||||
new=defender_client,
|
||||
):
|
||||
|
||||
# We import the check within the two mocks not to initialise the iam_client with some shared information from
|
||||
# the current_audit_info or the Defender service.
|
||||
from prowler.providers.azure.services.defender.defender_ensure_defender_for_arm_is_on.defender_ensure_defender_for_arm_is_on import (
|
||||
defender_ensure_defender_for_arm_is_on,
|
||||
)
|
||||
|
||||
# Once imported, we only need to instantiate the check's class
|
||||
check = defender_ensure_defender_for_arm_is_on()
|
||||
|
||||
# And then, call the execute() function to run the check
|
||||
# against the IAM client we've set up.
|
||||
result = check.execute()
|
||||
|
||||
# Last but not least, we need to assert all the fields
|
||||
# from the check's results
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for ARM from subscription {AZURE_SUSCRIPTION} is set to OFF (pricing tier not standard)"
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUSCRIPTION
|
||||
assert result[0].resource_name == "Defender plan ARM"
|
||||
assert result[0].resource_id == resource_id
|
||||
```
|
||||
|
||||
### Services
|
||||
|
||||
Coming soon ...
|
||||
@@ -1,6 +1,6 @@
|
||||
# Requirements
|
||||
|
||||
Prowler has been written in Python using the [AWS SDK (Boto3)](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html#) and [Azure SDK](https://learn.microsoft.com/en-us/python/api/overview/azure/?view=azure-python).
|
||||
Prowler has been written in Python using the [AWS SDK (Boto3)](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html#), [Azure SDK](https://azure.github.io/azure-sdk-for-python/) and [GCP API Python Client](https://github.com/googleapis/google-api-python-client/).
|
||||
## AWS
|
||||
|
||||
Since Prowler uses AWS Credentials under the hood, you can follow any authentication method as described [here](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-precedence).
|
||||
@@ -23,13 +23,20 @@ export AWS_SESSION_TOKEN="XXXXXXXXX"
|
||||
|
||||
Those credentials must be associated to a user or role with proper permissions to do all checks. To make sure, add the following AWS managed policies to the user or role being used:
|
||||
|
||||
- arn:aws:iam::aws:policy/SecurityAudit
|
||||
- arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
|
||||
- `arn:aws:iam::aws:policy/SecurityAudit`
|
||||
- `arn:aws:iam::aws:policy/job-function/ViewOnlyAccess`
|
||||
|
||||
> Moreover, some read-only additional permissions are needed for several checks, make sure you attach also the custom policy [prowler-additions-policy.json](https://github.com/prowler-cloud/prowler/blob/master/permissions/prowler-additions-policy.json) to the role you are using.
|
||||
|
||||
> If you want Prowler to send findings to [AWS Security Hub](https://aws.amazon.com/security-hub), make sure you also attach the custom policy [prowler-security-hub.json](https://github.com/prowler-cloud/prowler/blob/master/permissions/prowler-security-hub.json).
|
||||
|
||||
### Multi-Factor Authentication
|
||||
|
||||
If your IAM entity enforces MFA you can use `--mfa` and Prowler will ask you to input the following values to get a new session:
|
||||
|
||||
- ARN of your MFA device
|
||||
- TOTP (Time-Based One-Time Password)
|
||||
|
||||
## Azure
|
||||
|
||||
Prowler for azure supports the following authentication types:
|
||||
@@ -52,7 +59,7 @@ export AZURE_CLIENT_SECRET="XXXXXXX"
|
||||
If you try to execute Prowler with the `--sp-env-auth` flag and those variables are empty or not exported, the execution is going to fail.
|
||||
### AZ CLI / Browser / Managed Identity authentication
|
||||
|
||||
The other three cases does not need additional configuration, `--az-cli-auth` and `--managed-identity-auth` are automated options, `--browser-auth` needs the user to authenticate using the default browser to start the scan.
|
||||
The other three cases does not need additional configuration, `--az-cli-auth` and `--managed-identity-auth` are automated options. To use `--browser-auth` the user needs to authenticate against Azure using the default browser to start the scan, also `tenant-id` is required.
|
||||
|
||||
### Permissions
|
||||
|
||||
@@ -79,3 +86,21 @@ Regarding the subscription scope, Prowler by default scans all the subscriptions
|
||||
|
||||
- `Security Reader`
|
||||
- `Reader`
|
||||
|
||||
## Google Cloud
|
||||
|
||||
### GCP Authentication
|
||||
|
||||
Prowler will follow the same credentials search as [Google authentication libraries](https://cloud.google.com/docs/authentication/application-default-credentials#search_order):
|
||||
|
||||
1. [GOOGLE_APPLICATION_CREDENTIALS environment variable](https://cloud.google.com/docs/authentication/application-default-credentials#GAC)
|
||||
2. [User credentials set up by using the Google Cloud CLI](https://cloud.google.com/docs/authentication/application-default-credentials#personal)
|
||||
3. [The attached service account, returned by the metadata server](https://cloud.google.com/docs/authentication/application-default-credentials#attached-sa)
|
||||
|
||||
Those credentials must be associated to a user or service account with proper permissions to do all checks. To make sure, add the following roles to the member associated with the credentials:
|
||||
|
||||
- Viewer
|
||||
- Security Reviewer
|
||||
- Stackdriver Account Viewer
|
||||
|
||||
> By default, `prowler` will scan all accessible GCP Projects, use flag `--project-ids` to specify the projects to be scanned.
|
||||
|
||||
|
Before Width: | Height: | Size: 258 KiB After Width: | Height: | Size: 283 KiB |
BIN
docs/img/output-html.png
Normal file
|
After Width: | Height: | Size: 631 KiB |
1
docs/img/prowler-icon.svg
Normal file
|
After Width: | Height: | Size: 11 KiB |
1
docs/img/prowler-logo.svg
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
docs/img/quick-inventory.jpg
Normal file
|
After Width: | Height: | Size: 320 KiB |
|
Before Width: | Height: | Size: 220 KiB |
@@ -10,13 +10,13 @@
|
||||
For **Prowler v2 Documentation**, please go [here](https://github.com/prowler-cloud/prowler/tree/2.12.0) to the branch and its README.md.
|
||||
|
||||
- You are currently in the **Getting Started** section where you can find general information and requirements to help you start with the tool.
|
||||
- In the [Tutorials](tutorials/overview) section you will see how to take advantage of all the features in Prowler.
|
||||
- In the [Contact Us](contact) section you can find how to reach us out in case of technical issues.
|
||||
- In the [About](about) section you will find more information about the Prowler team and license.
|
||||
- In the [Tutorials](./tutorials/misc.md) section you will see how to take advantage of all the features in Prowler.
|
||||
- In the [Contact Us](./contact.md) section you can find how to reach us out in case of technical issues.
|
||||
- In the [About](./about.md) section you will find more information about the Prowler team and license.
|
||||
|
||||
## About Prowler
|
||||
|
||||
**Prowler** is an Open Source security tool to perform AWS and Azure security best practices assessments, audits, incident response, continuous monitoring, hardening and forensics readiness.
|
||||
**Prowler** is an Open Source security tool to perform AWS, Azure and Google Cloud security best practices assessments, audits, incident response, continuous monitoring, hardening and forensics readiness.
|
||||
|
||||
It contains hundreds of controls covering CIS, PCI-DSS, ISO27001, GDPR, HIPAA, FFIEC, SOC2, AWS FTR, ENS and custom security frameworks.
|
||||
|
||||
@@ -40,7 +40,7 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler-clo
|
||||
|
||||
* `Python >= 3.9`
|
||||
* `Python pip >= 3.9`
|
||||
* AWS and/or Azure credentials
|
||||
* AWS, GCP and/or Azure credentials
|
||||
|
||||
_Commands_:
|
||||
|
||||
@@ -54,7 +54,7 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler-clo
|
||||
_Requirements_:
|
||||
|
||||
* Have `docker` installed: https://docs.docker.com/get-docker/.
|
||||
* AWS and/or Azure credentials
|
||||
* AWS, GCP and/or Azure credentials
|
||||
* In the command below, change `-v` to your local directory path in order to access the reports.
|
||||
|
||||
_Commands_:
|
||||
@@ -71,7 +71,7 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler-clo
|
||||
|
||||
_Requirements for Ubuntu 20.04.3 LTS_:
|
||||
|
||||
* AWS and/or Azure credentials
|
||||
* AWS, GCP and/or Azure credentials
|
||||
* Install python 3.9 with: `sudo apt-get install python3.9`
|
||||
* Remove python 3.8 to avoid conflicts if you can: `sudo apt-get remove python3.8`
|
||||
* Make sure you have the python3 distutils package installed: `sudo apt-get install python3-distutils`
|
||||
@@ -87,12 +87,29 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler-clo
|
||||
prowler -v
|
||||
```
|
||||
|
||||
=== "GitHub"
|
||||
|
||||
_Requirements for Developers_:
|
||||
|
||||
* AWS, GCP and/or Azure credentials
|
||||
* `git`, `Python >= 3.9`, `pip` and `poetry` installed (`pip install poetry`)
|
||||
|
||||
_Commands_:
|
||||
|
||||
```
|
||||
git clone https://github.com/prowler-cloud/prowler
|
||||
cd prowler
|
||||
poetry shell
|
||||
poetry install
|
||||
python prowler.py -v
|
||||
```
|
||||
|
||||
=== "Amazon Linux 2"
|
||||
|
||||
_Requirements_:
|
||||
|
||||
* AWS and/or Azure credentials
|
||||
* Latest Amazon Linux 2 should come with Python 3.9 already installed however it may need pip. Install Python pip 3.9 with: `sudo dnf install -y python3-pip`.
|
||||
* AWS, GCP and/or Azure credentials
|
||||
* Latest Amazon Linux 2 should come with Python 3.9 already installed however it may need pip. Install Python pip 3.9 with: `sudo yum install -y python3-pip`.
|
||||
* Make sure setuptools for python is already installed with: `pip3 install setuptools`
|
||||
|
||||
_Commands_:
|
||||
@@ -103,6 +120,20 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler-clo
|
||||
prowler -v
|
||||
```
|
||||
|
||||
=== "Brew"
|
||||
|
||||
_Requirements_:
|
||||
|
||||
* `Brew` installed in your Mac or Linux
|
||||
* AWS, GCP and/or Azure credentials
|
||||
|
||||
_Commands_:
|
||||
|
||||
``` bash
|
||||
brew install prowler
|
||||
prowler -v
|
||||
```
|
||||
|
||||
=== "AWS CloudShell"
|
||||
|
||||
Prowler can be easely executed in AWS CloudShell but it has some prerequsites to be able to to so. AWS CloudShell is a container running with `Amazon Linux release 2 (Karoo)` that comes with Python 3.7, since Prowler requires Python >= 3.9 we need to first install a newer version of Python. Follow the steps below to successfully execute Prowler v3 in AWS CloudShell:
|
||||
@@ -154,7 +185,7 @@ The available versions of Prowler are the following:
|
||||
The container images are available here:
|
||||
|
||||
- [DockerHub](https://hub.docker.com/r/toniblyx/prowler/tags)
|
||||
- [AWS Public ECR](https://gallery.ecr.aws/o4g1s5r6/prowler)
|
||||
- [AWS Public ECR](https://gallery.ecr.aws/prowler-cloud/prowler)
|
||||
|
||||
## High level architecture
|
||||
|
||||
@@ -163,14 +194,14 @@ You can run Prowler from your workstation, an EC2 instance, Fargate or any other
|
||||

|
||||
## Basic Usage
|
||||
|
||||
To run Prowler, you will need to specify the provider (e.g aws or azure):
|
||||
To run Prowler, you will need to specify the provider (e.g aws, gcp or azure):
|
||||
> If no provider specified, AWS will be used for backward compatibility with most of v2 options.
|
||||
|
||||
```console
|
||||
prowler <provider>
|
||||
```
|
||||

|
||||
> Running the `prowler` command without options will use your environment variable credentials, see [Requirements](getting-started/requirements/) section to review the credentials settings.
|
||||
> Running the `prowler` command without options will use your environment variable credentials, see [Requirements](./getting-started/requirements.md) section to review the credentials settings.
|
||||
|
||||
If you miss the former output you can use `--verbose` but Prowler v3 is smoking fast, so you won't see much ;)
|
||||
|
||||
@@ -195,6 +226,7 @@ For executing specific checks or services you can use options `-c`/`checks` or `
|
||||
```console
|
||||
prowler azure --checks storage_blob_public_access_level_is_disabled
|
||||
prowler aws --services s3 ec2
|
||||
prowler gcp --services iam compute
|
||||
```
|
||||
|
||||
Also, checks and services can be excluded with options `-e`/`--excluded-checks` or `--excluded-services`:
|
||||
@@ -202,9 +234,10 @@ Also, checks and services can be excluded with options `-e`/`--excluded-checks`
|
||||
```console
|
||||
prowler aws --excluded-checks s3_bucket_public_access
|
||||
prowler azure --excluded-services defender iam
|
||||
prowler gcp --excluded-services kms
|
||||
```
|
||||
|
||||
More options and executions methods that will save your time in [Miscelaneous](tutorials/misc.md).
|
||||
More options and executions methods that will save your time in [Miscellaneous](tutorials/misc.md).
|
||||
|
||||
You can always use `-h`/`--help` to access to the usage information and all the possible options:
|
||||
|
||||
@@ -221,6 +254,8 @@ prowler aws --profile custom-profile -f us-east-1 eu-south-2
|
||||
```
|
||||
> By default, `prowler` will scan all AWS regions.
|
||||
|
||||
See more details about AWS Authentication in [Requirements](getting-started/requirements.md)
|
||||
|
||||
### Azure
|
||||
|
||||
With Azure you need to specify which auth method is going to be used:
|
||||
@@ -233,15 +268,37 @@ prowler azure --sp-env-auth
|
||||
prowler azure --az-cli-auth
|
||||
|
||||
# To use browser authentication
|
||||
prowler azure --browser-auth
|
||||
prowler azure --browser-auth --tenant-id "XXXXXXXX"
|
||||
|
||||
# To use managed identity auth
|
||||
prowler azure --managed-identity-auth
|
||||
```
|
||||
|
||||
More details in [Requirements](getting-started/requirements.md)
|
||||
See more details about Azure Authentication in [Requirements](getting-started/requirements.md)
|
||||
|
||||
Prowler by default scans all the subscriptions that is allowed to scan, if you want to scan a single subscription or various concrete subscriptions you can use the following flag (using az cli auth as example):
|
||||
Prowler by default scans all the subscriptions that is allowed to scan, if you want to scan a single subscription or various specific subscriptions you can use the following flag (using az cli auth as example):
|
||||
```console
|
||||
prowler azure --az-cli-auth --subscription-ids <subscription ID 1> <subscription ID 2> ... <subscription ID N>
|
||||
```
|
||||
|
||||
### Google Cloud
|
||||
|
||||
Prowler will use by default your User Account credentials, you can configure it using:
|
||||
|
||||
- `gcloud init` to use a new account
|
||||
- `gcloud config set account <account>` to use an existing account
|
||||
|
||||
Then, obtain your access credentials using: `gcloud auth application-default login`
|
||||
|
||||
Otherwise, you can generate and download Service Account keys in JSON format (refer to https://cloud.google.com/iam/docs/creating-managing-service-account-keys) and provide the location of the file with the following argument:
|
||||
|
||||
```console
|
||||
prowler gcp --credentials-file path
|
||||
```
|
||||
|
||||
Prowler by default scans all the GCP Projects that is allowed to scan, if you want to scan a single project or various specific projects you can use the following flag:
|
||||
```console
|
||||
prowler gcp --project-ids <Project ID 1> <Project ID 2> ... <Project ID N>
|
||||
```
|
||||
|
||||
See more details about GCP Authentication in [Requirements](getting-started/requirements.md)
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
This error is also related with a lack of system requirements. To improve performance, Prowler stores information in memory so it may need to be run in a system with more than 1GB of memory.
|
||||
|
||||
|
||||
See section [Logging](/tutorials/logging/) for further information or [contact us](/contact/).
|
||||
See section [Logging](./tutorials/logging.md) for further information or [contact us](./contact.md).
|
||||
|
||||
@@ -7,35 +7,80 @@ You can use `-w`/`--allowlist-file` with the path of your allowlist yaml file, b
|
||||
|
||||
## Allowlist Yaml File Syntax
|
||||
|
||||
### Account, Check and/or Region can be * to apply for all the cases
|
||||
### Resources is a list that can have either Regex or Keywords:
|
||||
### Account, Check and/or Region can be * to apply for all the cases.
|
||||
### Resources and tags are lists that can have either Regex or Keywords.
|
||||
### Tags is an optional list that matches on tuples of 'key=value' and are "ANDed" together.
|
||||
### Use an alternation Regex to match one of multiple tags with "ORed" logic.
|
||||
### For each check you can except Accounts, Regions, Resources and/or Tags.
|
||||
########################### ALLOWLIST EXAMPLE ###########################
|
||||
Allowlist:
|
||||
Accounts:
|
||||
"123456789012":
|
||||
Checks:
|
||||
Checks:
|
||||
"iam_user_hardware_mfa_enabled":
|
||||
Regions:
|
||||
Regions:
|
||||
- "us-east-1"
|
||||
Resources:
|
||||
Resources:
|
||||
- "user-1" # Will ignore user-1 in check iam_user_hardware_mfa_enabled
|
||||
- "user-2" # Will ignore user-2 in check iam_user_hardware_mfa_enabled
|
||||
"*":
|
||||
Regions:
|
||||
"ec2_*":
|
||||
Regions:
|
||||
- "*"
|
||||
Resources:
|
||||
- "test" # Will ignore every resource containing the string "test" in every account and region
|
||||
Resources:
|
||||
- "*" # Will ignore every EC2 check in every account and region
|
||||
"*":
|
||||
Regions:
|
||||
- "*"
|
||||
Resources:
|
||||
- "test"
|
||||
Tags:
|
||||
- "test=test" # Will ignore every resource containing the string "test" and the tags 'test=test' and
|
||||
- "project=test|project=stage" # either of ('project=test' OR project=stage) in account 123456789012 and every region
|
||||
|
||||
"*":
|
||||
Checks:
|
||||
Checks:
|
||||
"s3_bucket_object_versioning":
|
||||
Regions:
|
||||
Regions:
|
||||
- "eu-west-1"
|
||||
- "us-east-1"
|
||||
Resources:
|
||||
Resources:
|
||||
- "ci-logs" # Will ignore bucket "ci-logs" AND ALSO bucket "ci-logs-replica" in specified check and regions
|
||||
- "logs" # Will ignore EVERY BUCKET containing the string "logs" in specified check and regions
|
||||
- "[[:alnum:]]+-logs" # Will ignore all buckets containing the terms ci-logs, qa-logs, etc. in specified check and regions
|
||||
- ".+-logs" # Will ignore all buckets containing the terms ci-logs, qa-logs, etc. in specified check and regions
|
||||
"*":
|
||||
Regions:
|
||||
- "*"
|
||||
Resources:
|
||||
- "*"
|
||||
Tags:
|
||||
- "environment=dev" # Will ignore every resource containing the tag 'environment=dev' in every account and region
|
||||
|
||||
"*":
|
||||
Checks:
|
||||
"ecs_task_definitions_no_environment_secrets":
|
||||
Regions:
|
||||
- "*"
|
||||
Resources:
|
||||
- "*"
|
||||
Exceptions:
|
||||
Accounts:
|
||||
- "0123456789012"
|
||||
Regions:
|
||||
- "eu-west-1"
|
||||
- "eu-south-2" # Will ignore every resource in check ecs_task_definitions_no_environment_secrets except the ones in account 0123456789012 located in eu-south-2 or eu-west-1
|
||||
|
||||
"123456789012":
|
||||
Checks:
|
||||
"*":
|
||||
Regions:
|
||||
- "*"
|
||||
Resources:
|
||||
- "*"
|
||||
Exceptions:
|
||||
Resources:
|
||||
- "test"
|
||||
Tags:
|
||||
- "environment=prod" # Will ignore every resource except in account 123456789012 except the ones containing the string "test" and tag environment=prod
|
||||
|
||||
|
||||
## Supported Allowlist Locations
|
||||
@@ -70,6 +115,10 @@ prowler aws -w arn:aws:dynamodb:<region_name>:<account_id>:table/<table_name>
|
||||
- Checks (String): This field can contain either a Prowler Check Name or an `*` (which applies to all the scanned checks).
|
||||
- Regions (List): This field contains a list of regions where this allowlist rule is applied (it can also contains an `*` to apply all scanned regions).
|
||||
- Resources (List): This field contains a list of regex expressions that applies to the resources that are wanted to be allowlisted.
|
||||
- Tags (List): -Optional- This field contains a list of tuples in the form of 'key=value' that applies to the resources tags that are wanted to be allowlisted.
|
||||
- Exceptions (Map): -Optional- This field contains a map of lists of accounts/regions/resources/tags that are wanted to be excepted in the allowlist.
|
||||
|
||||
The following example will allowlist all resources in all accounts for the EC2 checks in the regions `eu-west-1` and `us-east-1` with the tags `environment=dev` and `environment=prod`, except the resources containing the string `test` in the account `012345678912` and region `eu-west-1` with the tag `environment=prod`:
|
||||
|
||||
<img src="../img/allowlist-row.png"/>
|
||||
|
||||
@@ -101,7 +150,7 @@ generates an Allowlist:
|
||||
```
|
||||
def handler(event, context):
|
||||
checks = {}
|
||||
checks["vpc_flow_logs_enabled"] = { "Regions": [ "*" ], "Resources": [ "" ] }
|
||||
checks["vpc_flow_logs_enabled"] = { "Regions": [ "*" ], "Resources": [ "" ], Optional("Tags"): [ "key:value" ] }
|
||||
|
||||
al = { "Allowlist": { "Accounts": { "*": { "Checks": checks } } } }
|
||||
return al
|
||||
|
||||
35
docs/tutorials/aws/authentication.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# AWS Authentication
|
||||
|
||||
Make sure you have properly configured your AWS-CLI with a valid Access Key and Region or declare AWS variables properly (or instance profile/role):
|
||||
|
||||
```console
|
||||
aws configure
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```console
|
||||
export AWS_ACCESS_KEY_ID="ASXXXXXXX"
|
||||
export AWS_SECRET_ACCESS_KEY="XXXXXXXXX"
|
||||
export AWS_SESSION_TOKEN="XXXXXXXXX"
|
||||
```
|
||||
|
||||
Those credentials must be associated to a user or role with proper permissions to do all checks. To make sure, add the following AWS managed policies to the user or role being used:
|
||||
|
||||
- `arn:aws:iam::aws:policy/SecurityAudit`
|
||||
- `arn:aws:iam::aws:policy/job-function/ViewOnlyAccess`
|
||||
|
||||
> Moreover, some read-only additional permissions are needed for several checks, make sure you attach also the custom policy [prowler-additions-policy.json](https://github.com/prowler-cloud/prowler/blob/master/permissions/prowler-additions-policy.json) to the role you are using.
|
||||
|
||||
> If you want Prowler to send findings to [AWS Security Hub](https://aws.amazon.com/security-hub), make sure you also attach the custom policy [prowler-security-hub.json](https://github.com/prowler-cloud/prowler/blob/master/permissions/prowler-security-hub.json).
|
||||
|
||||
## Multi-Factor Authentication
|
||||
|
||||
If your IAM entity enforces MFA you can use `--mfa` and Prowler will ask you to input the following values to get a new session:
|
||||
|
||||
- ARN of your MFA device
|
||||
- TOTP (Time-Based One-Time Password)
|
||||
|
||||
## STS Endpoint Region
|
||||
|
||||
If you are using Prowler in AWS regions that are not enabled by default you need to use the argument `--sts-endpoint-region` to point the AWS STS API calls `assume-role` and `get-caller-identity` to the non-default region, e.g.: `prowler aws --sts-endpoint-region eu-south-2`.
|
||||
@@ -1,7 +1,9 @@
|
||||
# Boto3 Retrier Configuration
|
||||
|
||||
Prowler's AWS Provider uses the Boto3 [Standard](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/retries.html) retry mode to assist in retrying client calls to AWS services when these kinds of errors or exceptions are experienced. This mode includes the following behaviours:
|
||||
|
||||
- A default value of 3 for maximum retry attempts. This can be overwritten with the `--aws-retries-max-attempts 5` argument.
|
||||
|
||||
- Retry attempts for an expanded list of errors/exceptions:
|
||||
```
|
||||
# Transient errors/exceptions
|
||||
@@ -26,6 +28,7 @@ Prowler's AWS Provider uses the Boto3 [Standard](https://boto3.amazonaws.com/v1/
|
||||
SlowDown
|
||||
EC2ThrottledException
|
||||
```
|
||||
|
||||
- Retry attempts on nondescriptive, transient error codes. Specifically, these HTTP status codes: 500, 502, 503, 504.
|
||||
|
||||
- Any retry attempt will include an exponential backoff by a base factor of 2 for a maximum backoff time of 20 seconds.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# AWS CloudShell
|
||||
|
||||
Prowler can be easely executed in AWS CloudShell but it has some prerequsites to be able to to so. AWS CloudShell is a container running with `Amazon Linux release 2 (Karoo)` that comes with Python 3.7, since Prowler requires Python >= 3.9 we need to first install a newer version of Python. Follow the steps below to successfully execute Prowler v3 in AWS CloudShell:
|
||||
Prowler can be easily executed in AWS CloudShell but it has some prerequisites to be able to to so. AWS CloudShell is a container running with `Amazon Linux release 2 (Karoo)` that comes with Python 3.7, since Prowler requires Python >= 3.9 we need to first install a newer version of Python. Follow the steps below to successfully execute Prowler v3 in AWS CloudShell:
|
||||
|
||||
- First install all dependences and then Python, in this case we need to compile it because there is not a package available at the time this document is written:
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Scan Multiple AWS Accounts
|
||||
|
||||
Prowler can scan multiple accounts when it is ejecuted from one account that can assume a role in those given accounts to scan using [Assume Role feature](role-assumption.md) and [AWS Organizations integration feature](organizations.md).
|
||||
Prowler can scan multiple accounts when it is executed from one account that can assume a role in those given accounts to scan using [Assume Role feature](role-assumption.md) and [AWS Organizations integration feature](organizations.md).
|
||||
|
||||
|
||||
## Scan multiple specific accounts sequentially
|
||||
@@ -41,7 +41,7 @@ for accountId in $ACCOUNTS_LIST; do
|
||||
done
|
||||
```
|
||||
|
||||
## Scan mutiple accounts from AWS Organizations in parallel
|
||||
## Scan multiple accounts from AWS Organizations in parallel
|
||||
|
||||
- Declare a variable with all the accounts to scan. To do so, get the list of your AWS accounts in your AWS Organization by running the following command (will create a variable with all your ACTIVE accounts). Remember to run that command with the permissions needed to get that information in your AWS Organizations Management account.
|
||||
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
# AWS Organizations
|
||||
## Get AWS Account details from your AWS Organization:
|
||||
## Get AWS Account details from your AWS Organization
|
||||
|
||||
Prowler allows you to get additional information of the scanned account in CSV and JSON outputs. When scanning a single account you get the Account ID as part of the output.
|
||||
|
||||
If you have AWS Organizations Prowler can get your account details like Account Name, Email, ARN, Organization ID and Tags and you will have them next to every finding in the CSV and JSON outputs.
|
||||
|
||||
- In order to do that you can use the option `-O`/`--organizations-role <organizations_role_arn>`. See the following sample command:
|
||||
In order to do that you can use the option `-O`/`--organizations-role <organizations_role_arn>`. See the following sample command:
|
||||
|
||||
```shell
|
||||
prowler aws \
|
||||
-O arn:aws:iam::<management_organizations_account_id>:role/<role_name>
|
||||
```
|
||||
prowler aws -O arn:aws:iam::<management_organizations_account_id>:role/<role_name>
|
||||
```
|
||||
> Make sure the role in your AWS Organizatiosn management account has the permissions `organizations:ListAccounts*` and `organizations:ListTagsForResource`.
|
||||
> Make sure the role in your AWS Organizations management account has the permissions `organizations:ListAccounts*` and `organizations:ListTagsForResource`.
|
||||
|
||||
- In that command Prowler will scan the account and getting the account details from the AWS Organizations management account assuming a role and creating two reports with those details in JSON and CSV.
|
||||
In that command Prowler will scan the account and getting the account details from the AWS Organizations management account assuming a role and creating two reports with those details in JSON and CSV.
|
||||
|
||||
In the JSON output below (redacted) you can see tags coded in base64 to prevent breaking CSV or JSON due to its format:
|
||||
|
||||
@@ -30,20 +31,28 @@ The additional fields in CSV header output are as follow:
|
||||
ACCOUNT_DETAILS_EMAIL,ACCOUNT_DETAILS_NAME,ACCOUNT_DETAILS_ARN,ACCOUNT_DETAILS_ORG,ACCOUNT_DETAILS_TAGS
|
||||
```
|
||||
|
||||
## Assume Role and across all accounts in AWS Organizations or just a list of accounts:
|
||||
## Extra: run Prowler across all accounts in AWS Organizations by assuming roles
|
||||
|
||||
If you want to run Prowler across all accounts of AWS Organizations you can do this:
|
||||
|
||||
- First get a list of accounts that are not suspended:
|
||||
1. First get a list of accounts that are not suspended:
|
||||
|
||||
```
|
||||
ACCOUNTS_IN_ORGS=$(aws organizations list-accounts --query Accounts[?Status==`ACTIVE`].Id --output text)
|
||||
```
|
||||
```shell
|
||||
ACCOUNTS_IN_ORGS=$(aws organizations list-accounts \
|
||||
--query "Accounts[?Status=='ACTIVE'].Id" \
|
||||
--output text \
|
||||
)
|
||||
```
|
||||
|
||||
- Then run Prowler to assume a role (same in all members) per each account, in this example it is just running one particular check:
|
||||
2. Then run Prowler to assume a role (same in all members) per each account:
|
||||
|
||||
```
|
||||
for accountId in $ACCOUNTS_IN_ORGS; do prowler aws -O arn:aws:iam::<management_organizations_account_id>:role/<role_name>; done
|
||||
```
|
||||
```shell
|
||||
for accountId in $ACCOUNTS_IN_ORGS;
|
||||
do
|
||||
prowler aws \
|
||||
-O arn:aws:iam::<management_organizations_account_id>:role/<role_name> \
|
||||
-R arn:aws:iam::"${accountId}":role/<role_name>;
|
||||
done
|
||||
```
|
||||
|
||||
- Using the same for loop it can be scanned a list of accounts with a variable like `ACCOUNTS_LIST='11111111111 2222222222 333333333'`
|
||||
> Using the same for loop it can be scanned a list of accounts with a variable like `ACCOUNTS_LIST='11111111111 2222222222 333333333'`
|
||||
|
||||
81
docs/tutorials/aws/regions-and-partitions.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# AWS Regions and Partitions
|
||||
|
||||
By default Prowler is able to scan the following AWS partitions:
|
||||
|
||||
- Commercial: `aws`
|
||||
- China: `aws-cn`
|
||||
- GovCloud (US): `aws-us-gov`
|
||||
|
||||
> To check the available regions for each partition and service please refer to the following document [aws_regions_by_service.json](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/aws/aws_regions_by_service.json)
|
||||
|
||||
It is important to take into consideration that to scan the China (`aws-cn`) or GovCloud (`aws-us-gov`) partitions it is either required to have a valid region for that partition in your AWS credentials or to specify the regions you want to audit for that partition using the `-f/--region` flag.
|
||||
> Please, refer to https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#configuring-credentials for more information about the AWS credentials configuration.
|
||||
|
||||
You can get more information about the available partitions and regions in the following [Botocore](https://github.com/boto/botocore) [file](https://github.com/boto/botocore/blob/22a19ea7c4c2c4dd7df4ab8c32733cba0c7597a4/botocore/data/partitions.json).
|
||||
## AWS China
|
||||
|
||||
To scan your AWS account in the China partition (`aws-cn`):
|
||||
|
||||
- Using the `-f/--region` flag:
|
||||
```
|
||||
prowler aws --region cn-north-1 cn-northwest-1
|
||||
```
|
||||
- Using the region configured in your AWS profile at `~/.aws/credentials` or `~/.aws/config`:
|
||||
```
|
||||
[default]
|
||||
aws_access_key_id = XXXXXXXXXXXXXXXXXXX
|
||||
aws_secret_access_key = XXXXXXXXXXXXXXXXXXX
|
||||
region = cn-north-1
|
||||
```
|
||||
> With this option all the partition regions will be scanned without the need of use the `-f/--region` flag
|
||||
|
||||
|
||||
## AWS GovCloud (US)
|
||||
|
||||
To scan your AWS account in the GovCloud (US) partition (`aws-us-gov`):
|
||||
|
||||
- Using the `-f/--region` flag:
|
||||
```
|
||||
prowler aws --region us-gov-east-1 us-gov-west-1
|
||||
```
|
||||
- Using the region configured in your AWS profile at `~/.aws/credentials` or `~/.aws/config`:
|
||||
```
|
||||
[default]
|
||||
aws_access_key_id = XXXXXXXXXXXXXXXXXXX
|
||||
aws_secret_access_key = XXXXXXXXXXXXXXXXXXX
|
||||
region = us-gov-east-1
|
||||
```
|
||||
> With this option all the partition regions will be scanned without the need of use the `-f/--region` flag
|
||||
|
||||
|
||||
## AWS ISO (US & Europe)
|
||||
|
||||
For the AWS ISO partitions, which are known as "secret partitions" and are air-gapped from the Internet, there is no builtin way to scan it. If you want to audit an AWS account in one of the AWS ISO partitions you should manually update the [aws_regions_by_service.json](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/aws/aws_regions_by_service.json) and include the partition, region and services, e.g.:
|
||||
```json
|
||||
"iam": {
|
||||
"regions": {
|
||||
"aws": [
|
||||
"eu-west-1",
|
||||
"us-east-1",
|
||||
],
|
||||
"aws-cn": [
|
||||
"cn-north-1",
|
||||
"cn-northwest-1"
|
||||
],
|
||||
"aws-us-gov": [
|
||||
"us-gov-east-1",
|
||||
"us-gov-west-1"
|
||||
],
|
||||
"aws-iso": [
|
||||
"aws-iso-global",
|
||||
"us-iso-east-1",
|
||||
"us-iso-west-1"
|
||||
],
|
||||
"aws-iso-b": [
|
||||
"aws-iso-b-global",
|
||||
"us-isob-east-1"
|
||||
],
|
||||
"aws-iso-e": [],
|
||||
}
|
||||
},
|
||||
```
|
||||
@@ -5,7 +5,7 @@ Prowler uses the AWS SDK (Boto3) underneath so it uses the same authentication m
|
||||
However, there are few ways to run Prowler against multiple accounts using IAM Assume Role feature depending on each use case:
|
||||
|
||||
1. You can just set up your custom profile inside `~/.aws/config` with all needed information about the role to assume then call it with `prowler aws -p/--profile your-custom-profile`.
|
||||
- An example profile that performs role-chaining is given below. The `credential_source` can either be set to `Environment`, `Ec2InstanceMetadata`, or `EcsContainer`.
|
||||
- An example profile that performs role-chaining is given below. The `credential_source` can either be set to `Environment`, `Ec2InstanceMetadata`, or `EcsContainer`.
|
||||
- Alternatively, you could use the `source_profile` instead of `credential_source` to specify a separate named profile that contains IAM user credentials with permission to assume the target the role. More information can be found [here](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html).
|
||||
```
|
||||
[profile crossaccountrole]
|
||||
@@ -23,6 +23,17 @@ prowler aws -R arn:aws:iam::<account_id>:role/<role_name>
|
||||
prowler aws -T/--session-duration <seconds> -I/--external-id <external_id> -R arn:aws:iam::<account_id>:role/<role_name>
|
||||
```
|
||||
|
||||
## STS Endpoint Region
|
||||
|
||||
If you are using Prowler in AWS regions that are not enabled by default you need to use the argument `--sts-endpoint-region` to point the AWS STS API calls `assume-role` and `get-caller-identity` to the non-default region, e.g.: `prowler aws --sts-endpoint-region eu-south-2`.
|
||||
|
||||
## Role MFA
|
||||
|
||||
If your IAM Role has MFA configured you can use `--mfa` along with `-R`/`--role <role_arn>` and Prowler will ask you to input the following values to get a new temporary session for the IAM Role provided:
|
||||
|
||||
- ARN of your MFA device
|
||||
- TOTP (Time-Based One-Time Password)
|
||||
|
||||
## Create Role
|
||||
|
||||
To create a role to be assumed in one or multiple accounts you can use either as CloudFormation Stack or StackSet the following [template](https://github.com/prowler-cloud/prowler/blob/master/permissions/create_role_to_assume_cfn.yaml) and adapt it.
|
||||
|
||||
26
docs/tutorials/aws/s3.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Send report to AWS S3 Bucket
|
||||
|
||||
To save your report in an S3 bucket, use `-B`/`--output-bucket`.
|
||||
|
||||
```sh
|
||||
prowler <provider> -B my-bucket
|
||||
```
|
||||
|
||||
If you can use a custom folder and/or filename, use `-o`/`--output-directory` and/or `-F`/`--output-filename`.
|
||||
|
||||
```sh
|
||||
prowler <provider> \
|
||||
-B my-bucket \
|
||||
--output-directory test-folder \
|
||||
--output-filename output-filename
|
||||
```
|
||||
|
||||
By default Prowler sends HTML, JSON and CSV output formats, if you want to send a custom output format or a single one of the defaults you can specify it with the `-M`/`--output-modes` flag.
|
||||
|
||||
```sh
|
||||
prowler <provider> -M csv -B my-bucket
|
||||
```
|
||||
|
||||
> In the case you do not want to use the assumed role credentials but the initial credentials to put the reports into the S3 bucket, use `-D`/`--output-bucket-no-assume` instead of `-B`/`--output-bucket`.
|
||||
|
||||
> Make sure that the used credentials have `s3:PutObject` permissions in the S3 path where the reports are going to be uploaded.
|
||||
@@ -13,35 +13,55 @@ Before sending findings to Prowler, you will need to perform next steps:
|
||||
- Using the AWS Management Console:
|
||||

|
||||
3. Allow Prowler to import its findings to AWS Security Hub by adding the policy below to the role or user running Prowler:
|
||||
- [prowler-security-hub.json](https://github.com/prowler-cloud/prowler/blob/master/iam/prowler-security-hub.json)
|
||||
- [prowler-security-hub.json](https://github.com/prowler-cloud/prowler/blob/master/permissions/prowler-security-hub.json)
|
||||
|
||||
Once it is enabled, it is as simple as running the command below (for all regions):
|
||||
|
||||
```sh
|
||||
./prowler aws -S
|
||||
prowler aws -S
|
||||
```
|
||||
|
||||
or for only one filtered region like eu-west-1:
|
||||
|
||||
```sh
|
||||
./prowler -S -f eu-west-1
|
||||
prowler -S -f eu-west-1
|
||||
```
|
||||
|
||||
> **Note 1**: It is recommended to send only fails to Security Hub and that is possible adding `-q` to the command.
|
||||
|
||||
> **Note 2**: Since Prowler perform checks to all regions by defauls you may need to filter by region when runing Security Hub integration, as shown in the example above. Remember to enable Security Hub in the region or regions you need by calling `aws securityhub enable-security-hub --region <region>` and run Prowler with the option `-f <region>` (if no region is used it will try to push findings in all regions hubs).
|
||||
> **Note 2**: Since Prowler perform checks to all regions by default you may need to filter by region when running Security Hub integration, as shown in the example above. Remember to enable Security Hub in the region or regions you need by calling `aws securityhub enable-security-hub --region <region>` and run Prowler with the option `-f <region>` (if no region is used it will try to push findings in all regions hubs). Prowler will send findings to the Security Hub on the region where the scanned resource is located.
|
||||
|
||||
> **Note 3** to have updated findings in Security Hub you have to run Prowler periodically. Once a day or every certain amount of hours.
|
||||
> **Note 3**: To have updated findings in Security Hub you have to run Prowler periodically. Once a day or every certain amount of hours.
|
||||
|
||||
Once you run findings for first time you will be able to see Prowler findings in Findings section:
|
||||
|
||||

|
||||
|
||||
## Send findings to Security Hub assuming an IAM Role
|
||||
|
||||
When you are auditing a multi-account AWS environment, you can send findings to a Security Hub of another account by assuming an IAM role from that account using the `-R` flag in the Prowler command:
|
||||
|
||||
```sh
|
||||
prowler -S -R arn:aws:iam::123456789012:role/ProwlerExecRole
|
||||
```
|
||||
|
||||
> Remember that the used role needs to have permissions to send findings to Security Hub. To get more information about the permissions required, please refer to the following IAM policy [prowler-security-hub.json](https://github.com/prowler-cloud/prowler/blob/master/permissions/prowler-security-hub.json)
|
||||
|
||||
|
||||
## Send only failed findings to Security Hub
|
||||
|
||||
When using Security Hub it is recommended to send only the failed findings generated. To follow that recommendation you could add the `-q` flag to the Prowler command:
|
||||
|
||||
```sh
|
||||
prowler -S -q
|
||||
```
|
||||
|
||||
|
||||
## Skip sending updates of findings to Security Hub
|
||||
|
||||
By default, Prowler archives all its findings in Security Hub that have not appeared in the last scan.
|
||||
You can skip this logic by using the option `--skip-sh-update` so Prowler will not archive older findings:
|
||||
|
||||
```sh
|
||||
./prowler -S --skip-sh-update
|
||||
prowler -S --skip-sh-update
|
||||
```
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Check mapping between Prowler v3 and v2
|
||||
|
||||
Prowler v3 comes with different identifiers but we maintained the same checks that were implemented in v2. The reason for this change is because in previows versions of Prowler, check names were mostly based on CIS Benchmark for AWS. In v3 all checks are independent from any security framework and they have its own name and ID.
|
||||
Prowler v3 comes with different identifiers but we maintained the same checks that were implemented in v2. The reason for this change is because in previous versions of Prowler, check names were mostly based on CIS Benchmark for AWS. In v3 all checks are independent from any security framework and they have its own name and ID.
|
||||
|
||||
If you need more information about how new compliance implementation works in Prowler v3 see [Compliance](../../compliance/) section.
|
||||
If you need more information about how new compliance implementation works in Prowler v3 see [Compliance](../compliance.md) section.
|
||||
|
||||
```
|
||||
checks_v3_to_v2_mapping = {
|
||||
@@ -31,7 +31,7 @@ checks_v3_to_v2_mapping = {
|
||||
"awslambda_function_url_cors_policy": "extra7180",
|
||||
"awslambda_function_url_public": "extra7179",
|
||||
"awslambda_function_using_supported_runtimes": "extra762",
|
||||
"cloudformation_outputs_find_secrets": "extra742",
|
||||
"cloudformation_stack_outputs_find_secrets": "extra742",
|
||||
"cloudformation_stacks_termination_protection_enabled": "extra7154",
|
||||
"cloudfront_distributions_field_level_encryption_enabled": "extra767",
|
||||
"cloudfront_distributions_geo_restrictions_enabled": "extra732",
|
||||
@@ -113,7 +113,6 @@ checks_v3_to_v2_mapping = {
|
||||
"ec2_securitygroup_allow_wide_open_public_ipv4": "extra778",
|
||||
"ec2_securitygroup_default_restrict_traffic": "check43",
|
||||
"ec2_securitygroup_from_launch_wizard": "extra7173",
|
||||
"ec2_securitygroup_in_use_without_ingress_filtering": "extra74",
|
||||
"ec2_securitygroup_not_used": "extra75",
|
||||
"ec2_securitygroup_with_many_ingress_egress_rules": "extra777",
|
||||
"ecr_repositories_lifecycle_policy_enabled": "extra7194",
|
||||
@@ -138,7 +137,6 @@ checks_v3_to_v2_mapping = {
|
||||
"elbv2_internet_facing": "extra79",
|
||||
"elbv2_listeners_underneath": "extra7158",
|
||||
"elbv2_logging_enabled": "extra717",
|
||||
"elbv2_request_smugling": "extra7142",
|
||||
"elbv2_ssl_listeners": "extra793",
|
||||
"elbv2_waf_acl_attached": "extra7129",
|
||||
"emr_cluster_account_public_block_enabled": "extra7178",
|
||||
|
||||
@@ -18,10 +18,10 @@ prowler azure --sp-env-auth
|
||||
prowler azure --az-cli-auth
|
||||
|
||||
# To use browser authentication
|
||||
prowler azure --browser-auth
|
||||
prowler azure --browser-auth --tenant-id "XXXXXXXX"
|
||||
|
||||
# To use managed identity auth
|
||||
prowler azure --managed-identity-auth
|
||||
```
|
||||
|
||||
To use Prowler you need to set up also the permissions required to access your resources in your Azure account, to more details refer to [Requirements](/getting-started/requirements)
|
||||
To use Prowler you need to set up also the permissions required to access your resources in your Azure account, to more details refer to [Requirements](../../getting-started/requirements.md)
|
||||
|
||||
@@ -13,6 +13,7 @@ Currently, the available frameworks are:
|
||||
- `ens_rd2022_aws`
|
||||
- `aws_audit_manager_control_tower_guardrails_aws`
|
||||
- `aws_foundational_security_best_practices_aws`
|
||||
- `aws_well_architected_framework_security_pillar_aws`
|
||||
- `cisa_aws`
|
||||
- `fedramp_low_revision_4_aws`
|
||||
- `fedramp_moderate_revision_4_aws`
|
||||
@@ -81,36 +82,4 @@ Standard results will be shown and additionally the framework information as the
|
||||
|
||||
## Create and contribute adding other Security Frameworks
|
||||
|
||||
If you want to create or contribute with your own security frameworks or add public ones to Prowler you need to make sure the checks are available if not you have to create your own. Then create a compliance file per provider like in `prowler/compliance/aws/` and name it as `<framework>_<version>_<provider>.json` then follow the following format to create yours.
|
||||
|
||||
Each file version of a framework will have the following structure at high level with the case that each framework needs to be generally identified), one requirement can be also called one control but one requirement can be linked to multiple prowler checks.:
|
||||
|
||||
- `Framework`: string. Indistiguish name of the framework, like CIS
|
||||
- `Provider`: string. Provider where the framework applies, such as AWS, Azure, OCI,...
|
||||
- `Version`: string. Version of the framework itself, like 1.4 for CIS.
|
||||
- `Requirements`: array of objects. Include all requirements or controls with the mapping to Prowler.
|
||||
- `Requirements_Id`: string. Unique identifier per each requirement in the specific framework
|
||||
- `Requirements_Description`: string. Description as in the framework.
|
||||
- `Requirements_Attributes`: array of objects. Includes all needed attributes per each requirement, like levels, sections, etc. Whatever helps to create a dedicated report with the result of the findings. Attributes would be taken as closely as possible from the framework's own terminology directly.
|
||||
- `Requirements_Checks`: array. Prowler checks that are needed to prove this requirement. It can be one or multiple checks. In case of no automation possible this can be empty.
|
||||
|
||||
```
|
||||
{
|
||||
"Framework": "<framework>-<provider>",
|
||||
"Version": "<version>",
|
||||
"Requirements": [
|
||||
{
|
||||
"Id": "<unique-id>",
|
||||
"Description": "Requiemente full description",
|
||||
"Checks": [
|
||||
"Here is the prowler check or checks that is going to be executed"
|
||||
],
|
||||
"Attributes": [
|
||||
{
|
||||
<Add here your custom attributes.>
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Finally, to have a proper output file for your reports, your framework data model has to be created in `prowler/lib/outputs/models.py` and also the CLI table output in `prowler/lib/outputs/compliance.py`.
|
||||
This information is part of the Developer Guide and can be found here: https://docs.prowler.cloud/en/latest/tutorials/developer-guide/.
|
||||
|
||||
@@ -1,76 +1,111 @@
|
||||
# Configuration File
|
||||
Several Prowler's checks have user configurable variables that can be modified in a common **configuration file**.
|
||||
This file can be found in the following path:
|
||||
Several Prowler's checks have user configurable variables that can be modified in a common **configuration file**. This file can be found in the following [path](https://github.com/prowler-cloud/prowler/blob/master/prowler/config/config.yaml):
|
||||
```
|
||||
prowler/config/config.yaml
|
||||
```
|
||||
|
||||
## Configurable Checks
|
||||
The following list includes all the checks with configurable variables that can be changed in the mentioned configuration yaml file:
|
||||
Also you can input a custom configuration file using the `--config-file` argument.
|
||||
|
||||
1. aws.ec2_elastic_ip_shodan
|
||||
- shodan_api_key (String)
|
||||
- aws.ec2_securitygroup_with_many_ingress_egress_rules
|
||||
- max_security_group_rules (Integer)
|
||||
- aws.ec2_instance_older_than_specific_days
|
||||
- max_ec2_instance_age_in_days (Integer)
|
||||
- aws.vpc_endpoint_connections_trust_boundaries
|
||||
- trusted_account_ids (List of Strings)
|
||||
- aws.vpc_endpoint_services_allowed_principals_trust_boundaries
|
||||
- trusted_account_ids (List of Strings)
|
||||
- aws.cloudwatch_log_group_retention_policy_specific_days_enabled
|
||||
- log_group_retention_days (Integer)
|
||||
- aws.appstream_fleet_session_idle_disconnect_timeout
|
||||
- max_idle_disconnect_timeout_in_seconds (Integer)
|
||||
- aws.appstream_fleet_session_disconnect_timeout
|
||||
- max_disconnect_timeout_in_seconds (Integer)
|
||||
- aws.appstream_fleet_maximum_session_duration
|
||||
- max_session_duration_seconds (Integer)
|
||||
- aws.awslambda_function_using_supported_runtimes
|
||||
- obsolete_lambda_runtimes (List of Strings)
|
||||
## AWS
|
||||
|
||||
## Config Yaml File
|
||||
### Configurable Checks
|
||||
The following list includes all the AWS checks with configurable variables that can be changed in the configuration yaml file:
|
||||
|
||||
# AWS EC2 Configuration
|
||||
# aws.ec2_elastic_ip_shodan
|
||||
shodan_api_key: null
|
||||
# aws.ec2_securitygroup_with_many_ingress_egress_rules --> by default is 50 rules
|
||||
max_security_group_rules: 50
|
||||
# aws.ec2_instance_older_than_specific_days --> by default is 6 months (180 days)
|
||||
max_ec2_instance_age_in_days: 180
|
||||
| Check Name | Value | Type |
|
||||
|---|---|---|
|
||||
| `ec2_elastic_ip_shodan` | `shodan_api_key` | String |
|
||||
| `ec2_securitygroup_with_many_ingress_egress_rules` | `max_security_group_rules` | Integer |
|
||||
| `ec2_instance_older_than_specific_days` | `max_ec2_instance_age_in_days` | Integer |
|
||||
| `vpc_endpoint_connections_trust_boundaries` | `trusted_account_ids` | List of Strings |
|
||||
| `vpc_endpoint_services_allowed_principals_trust_boundaries` | `trusted_account_ids` | List of Strings |
|
||||
| `cloudwatch_log_group_retention_policy_specific_days_enabled` | `log_group_retention_days` | Integer |
|
||||
| `appstream_fleet_session_idle_disconnect_timeout` | `max_idle_disconnect_timeout_in_seconds` | Integer |
|
||||
| `appstream_fleet_session_disconnect_timeout` | `max_disconnect_timeout_in_seconds` | Integer |
|
||||
| `appstream_fleet_maximum_session_duration` | `max_session_duration_seconds` | Integer |
|
||||
| `awslambda_function_using_supported_runtimes` | `obsolete_lambda_runtimes` | Integer |
|
||||
| `organizations_scp_check_deny_regions` | `organizations_enabled_regions` | List of Strings |
|
||||
| `organizations_delegated_administrators` | `organizations_trusted_delegated_administrators` | List of Strings |
|
||||
| `ecr_repositories_scan_vulnerabilities_in_latest_image` | `ecr_repository_vulnerability_minimum_severity` | String |
|
||||
|
||||
# AWS VPC Configuration (vpc_endpoint_connections_trust_boundaries, vpc_endpoint_services_allowed_principals_trust_boundaries)
|
||||
# Single account environment: No action required. The AWS account number will be automatically added by the checks.
|
||||
# Multi account environment: Any additional trusted account number should be added as a space separated list, e.g.
|
||||
# trusted_account_ids : ["123456789012", "098765432109", "678901234567"]
|
||||
trusted_account_ids: []
|
||||
## Azure
|
||||
|
||||
# AWS Cloudwatch Configuration
|
||||
# aws.cloudwatch_log_group_retention_policy_specific_days_enabled --> by default is 365 days
|
||||
log_group_retention_days: 365
|
||||
### Configurable Checks
|
||||
|
||||
# AWS AppStream Session Configuration
|
||||
# aws.appstream_fleet_session_idle_disconnect_timeout
|
||||
max_idle_disconnect_timeout_in_seconds: 600 # 10 Minutes
|
||||
# aws.appstream_fleet_session_disconnect_timeout
|
||||
max_disconnect_timeout_in_seconds: 300 # 5 Minutes
|
||||
# aws.appstream_fleet_maximum_session_duration
|
||||
max_session_duration_seconds: 36000 # 10 Hours
|
||||
## GCP
|
||||
|
||||
# AWS Lambda Configuration
|
||||
# aws.awslambda_function_using_supported_runtimes
|
||||
obsolete_lambda_runtimes:
|
||||
### Configurable Checks
|
||||
|
||||
## Config YAML File Structure
|
||||
> This is the new Prowler configuration file format. The old one without provider keys is still compatible just for the AWS provider.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
# AWS Configuration
|
||||
aws:
|
||||
# AWS EC2 Configuration
|
||||
# aws.ec2_elastic_ip_shodan
|
||||
shodan_api_key: null
|
||||
# aws.ec2_securitygroup_with_many_ingress_egress_rules --> by default is 50 rules
|
||||
max_security_group_rules: 50
|
||||
# aws.ec2_instance_older_than_specific_days --> by default is 6 months (180 days)
|
||||
max_ec2_instance_age_in_days: 180
|
||||
|
||||
# AWS VPC Configuration (vpc_endpoint_connections_trust_boundaries, vpc_endpoint_services_allowed_principals_trust_boundaries)
|
||||
# Single account environment: No action required. The AWS account number will be automatically added by the checks.
|
||||
# Multi account environment: Any additional trusted account number should be added as a space separated list, e.g.
|
||||
# trusted_account_ids : ["123456789012", "098765432109", "678901234567"]
|
||||
trusted_account_ids: []
|
||||
|
||||
# AWS Cloudwatch Configuration
|
||||
# aws.cloudwatch_log_group_retention_policy_specific_days_enabled --> by default is 365 days
|
||||
log_group_retention_days: 365
|
||||
|
||||
# AWS AppStream Session Configuration
|
||||
# aws.appstream_fleet_session_idle_disconnect_timeout
|
||||
max_idle_disconnect_timeout_in_seconds: 600 # 10 Minutes
|
||||
# aws.appstream_fleet_session_disconnect_timeout
|
||||
max_disconnect_timeout_in_seconds: 300 # 5 Minutes
|
||||
# aws.appstream_fleet_maximum_session_duration
|
||||
max_session_duration_seconds: 36000 # 10 Hours
|
||||
|
||||
# AWS Lambda Configuration
|
||||
# aws.awslambda_function_using_supported_runtimes
|
||||
obsolete_lambda_runtimes:
|
||||
[
|
||||
"python3.6",
|
||||
"python2.7",
|
||||
"nodejs4.3",
|
||||
"nodejs4.3-edge",
|
||||
"nodejs6.10",
|
||||
"nodejs",
|
||||
"nodejs8.10",
|
||||
"nodejs10.x",
|
||||
"dotnetcore1.0",
|
||||
"dotnetcore2.0",
|
||||
"dotnetcore2.1",
|
||||
"ruby2.5",
|
||||
"python3.6",
|
||||
"python2.7",
|
||||
"nodejs4.3",
|
||||
"nodejs4.3-edge",
|
||||
"nodejs6.10",
|
||||
"nodejs",
|
||||
"nodejs8.10",
|
||||
"nodejs10.x",
|
||||
"dotnetcore1.0",
|
||||
"dotnetcore2.0",
|
||||
"dotnetcore2.1",
|
||||
"ruby2.5",
|
||||
]
|
||||
|
||||
# AWS Organizations
|
||||
# organizations_scp_check_deny_regions
|
||||
# organizations_enabled_regions: [
|
||||
# 'eu-central-1',
|
||||
# 'eu-west-1',
|
||||
# "us-east-1"
|
||||
# ]
|
||||
organizations_enabled_regions: []
|
||||
organizations_trusted_delegated_administrators: []
|
||||
|
||||
# AWS ECR
|
||||
# ecr_repositories_scan_vulnerabilities_in_latest_image
|
||||
# CRITICAL
|
||||
# HIGH
|
||||
# MEDIUM
|
||||
ecr_repository_vulnerability_minimum_severity: "MEDIUM"
|
||||
|
||||
# Azure Configuration
|
||||
azure:
|
||||
|
||||
# GCP Configuration
|
||||
gcp:
|
||||
|
||||
```
|
||||
|
||||
29
docs/tutorials/gcp/authentication.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# GCP authentication
|
||||
|
||||
Prowler will use by default your User Account credentials, you can configure it using:
|
||||
|
||||
- `gcloud init` to use a new account
|
||||
- `gcloud config set account <account>` to use an existing account
|
||||
|
||||
Then, obtain your access credentials using: `gcloud auth application-default login`
|
||||
|
||||
Otherwise, you can generate and download Service Account keys in JSON format (refer to https://cloud.google.com/iam/docs/creating-managing-service-account-keys) and provide the location of the file with the following argument:
|
||||
|
||||
```console
|
||||
prowler gcp --credentials-file path
|
||||
```
|
||||
|
||||
> `prowler` will scan the GCP project associated with the credentials.
|
||||
|
||||
|
||||
Prowler will follow the same credentials search as [Google authentication libraries](https://cloud.google.com/docs/authentication/application-default-credentials#search_order):
|
||||
|
||||
1. [GOOGLE_APPLICATION_CREDENTIALS environment variable](https://cloud.google.com/docs/authentication/application-default-credentials#GAC)
|
||||
2. [User credentials set up by using the Google Cloud CLI](https://cloud.google.com/docs/authentication/application-default-credentials#personal)
|
||||
3. [The attached service account, returned by the metadata server](https://cloud.google.com/docs/authentication/application-default-credentials#attached-sa)
|
||||
|
||||
Those credentials must be associated to a user or service account with proper permissions to do all checks. To make sure, add the following roles to the member associated with the credentials:
|
||||
|
||||
- Viewer
|
||||
- Security Reviewer
|
||||
- Stackdriver Account Viewer
|
||||
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 94 KiB |
BIN
docs/tutorials/img/create-slack-app.png
Normal file
|
After Width: | Height: | Size: 61 KiB |
BIN
docs/tutorials/img/install-in-slack-workspace.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
docs/tutorials/img/integrate-slack-app.png
Normal file
|
After Width: | Height: | Size: 200 KiB |
BIN
docs/tutorials/img/slack-app-token.png
Normal file
|
After Width: | Height: | Size: 456 KiB |
BIN
docs/tutorials/img/slack-prowler-message.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
36
docs/tutorials/integrations.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Integrations
|
||||
|
||||
## Slack
|
||||
|
||||
Prowler can be integrated with [Slack](https://slack.com/) to send a summary of the execution having configured a Slack APP in your channel with the following command:
|
||||
|
||||
```sh
|
||||
prowler <provider> --slack
|
||||
```
|
||||
|
||||

|
||||
|
||||
> Slack integration needs SLACK_API_TOKEN and SLACK_CHANNEL_ID environment variables.
|
||||
### Configuration
|
||||
|
||||
To configure the Slack Integration, follow the next steps:
|
||||
|
||||
1. Create a Slack Application:
|
||||
- Go to [Slack API page](https://api.slack.com/tutorials/tracks/getting-a-token), scroll down to the *Create app* button and select your workspace:
|
||||

|
||||
|
||||
- Install the application in your selected workspaces:
|
||||

|
||||
|
||||
- Get the *Slack App OAuth Token* that Prowler needs to send the message:
|
||||

|
||||
|
||||
2. Optionally, create a Slack Channel (you can use an existing one)
|
||||
|
||||
3. Integrate the created Slack App to your Slack channel:
|
||||
- Click on the channel, go to the Integrations tab, and Add an App.
|
||||

|
||||
|
||||
4. Set the following environment variables that Prowler will read:
|
||||
- `SLACK_API_TOKEN`: the *Slack App OAuth Token* that was previously get.
|
||||
- `SLACK_CHANNEL_ID`: the name of your Slack Channel where Prowler will send the message.
|
||||
@@ -51,15 +51,36 @@ prowler <provider> -e/--excluded-checks ec2 rds
|
||||
```console
|
||||
prowler <provider> -C/--checks-file <checks_list>.json
|
||||
```
|
||||
|
||||
## Severities
|
||||
Each check of Prowler has a severity, there are options related with it:
|
||||
|
||||
- List the available checks in the provider:
|
||||
## Custom Checks
|
||||
Prowler allows you to include your custom checks with the flag:
|
||||
```console
|
||||
prowler <provider> --list-severities
|
||||
prowler <provider> -x/--checks-folder <custom_checks_folder>
|
||||
```
|
||||
- Execute specific severity(s):
|
||||
> S3 URIs are also supported as folders for custom checks, e.g. s3://bucket/prefix/checks_folder/. Make sure that the used credentials have s3:GetObject permissions in the S3 path where the custom checks are located.
|
||||
|
||||
The custom checks folder must contain one subfolder per check, each subfolder must be named as the check and must contain:
|
||||
|
||||
- An empty `__init__.py`: to make Python treat this check folder as a package.
|
||||
- A `check_name.py` containing the check's logic.
|
||||
- A `check_name.metadata.json` containing the check's metadata.
|
||||
>The check name must start with the service name followed by an underscore (e.g., ec2_instance_public_ip).
|
||||
|
||||
To see more information about how to write checks see the [Developer Guide](../developer-guide/checks.md#create-a-new-check-for-a-provider).
|
||||
|
||||
> If you want to run ONLY your custom check(s), import it with -x (--checks-folder) and then run it with -c (--checks), e.g.:
|
||||
```console
|
||||
prowler aws -x s3://bucket/prowler/providers/aws/services/s3/s3_bucket_policy/ -c s3_bucket_policy
|
||||
```
|
||||
|
||||
## Severities
|
||||
Each of Prowler's checks has a severity, which can be:
|
||||
- informational
|
||||
- low
|
||||
- medium
|
||||
- high
|
||||
- critical
|
||||
|
||||
To execute specific severity(s):
|
||||
```console
|
||||
prowler <provider> --severity critical high
|
||||
```
|
||||
|
||||
@@ -6,12 +6,12 @@ Prowler has some checks that analyse pentesting risks (Secrets, Internet Exposed
|
||||
|
||||
Prowler uses `detect-secrets` library to search for any secrets that are stores in plaintext within your environment.
|
||||
|
||||
The actual checks that have this funcionality are:
|
||||
The actual checks that have this functionality are:
|
||||
|
||||
1. autoscaling_find_secrets_ec2_launch_configuration
|
||||
- awslambda_function_no_secrets_in_code
|
||||
- awslambda_function_no_secrets_in_variables
|
||||
- cloudformation_outputs_find_secrets
|
||||
- cloudformation_stack_outputs_find_secrets
|
||||
- ec2_instance_secrets_user_data
|
||||
- ecs_task_definitions_no_environment_secrets
|
||||
- ssm_document_secrets
|
||||
@@ -33,9 +33,8 @@ Several checks analyse resources that are exposed to the Internet, these are:
|
||||
- ec2_instance_internet_facing_with_instance_profile
|
||||
- ec2_instance_public_ip
|
||||
- ec2_networkacl_allow_ingress_any_port
|
||||
- ec2_securitygroup_allow_ingress_from_internet_to_any_port
|
||||
- ec2_securitygroup_allow_wide_open_public_ipv4
|
||||
- ec2_securitygroup_in_use_without_ingress_filtering
|
||||
- ec2_securitygroup_allow_ingress_from_internet_to_any_port
|
||||
- ecr_repositories_not_publicly_accessible
|
||||
- eks_control_plane_endpoint_access_restricted
|
||||
- eks_endpoints_not_publicly_accessible
|
||||
|
||||
@@ -14,4 +14,7 @@ prowler <provider> -i
|
||||
|
||||
- Also, it creates by default a CSV and JSON to see detailed information about the resources extracted.
|
||||
|
||||

|
||||

|
||||
|
||||
## Objections
|
||||
The inventorying process is done with `resourcegroupstaggingapi` calls which means that only resources they have or have had tags will appear (except for the IAM and S3 resources which are done with Boto3 API calls).
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# Reporting
|
||||
|
||||
By default, Prowler will generate a CSV, JSON and a HTML report, however you could generate a JSON-ASFF (used by AWS Security Hub) report with `-M` or `--output-modes`:
|
||||
By default, Prowler will generate a CSV, JSON, JSON-OCSF and a HTML report, however you could generate a JSON-ASFF (used by AWS Security Hub) report with `-M` or `--output-modes`:
|
||||
|
||||
```console
|
||||
prowler <provider> -M csv json json-asff html
|
||||
prowler <provider> -M csv json json-ocsf json-asff html
|
||||
```
|
||||
|
||||
## Custom Output Flags
|
||||
@@ -19,21 +19,11 @@ prowler <provider> -M csv json json-asff html -F <custom_report_name>
|
||||
```console
|
||||
prowler <provider> -M csv json json-asff html -o <custom_report_directory>
|
||||
```
|
||||
> Both flags can be used simultainously to provide a custom directory and filename.
|
||||
> Both flags can be used simultaneously to provide a custom directory and filename.
|
||||
```console
|
||||
prowler <provider> -M csv json json-asff html -F <custom_report_name> -o <custom_report_directory>
|
||||
prowler <provider> -M csv json json-asff html \
|
||||
-F <custom_report_name> -o <custom_report_directory>
|
||||
```
|
||||
## Send report to AWS S3 Bucket
|
||||
|
||||
To save your report in an S3 bucket, use `-B`/`--output-bucket` to define a custom output bucket along with `-M` to define the output format that is going to be uploaded to S3:
|
||||
|
||||
```sh
|
||||
prowler <provider> -M csv -B my-bucket/folder/
|
||||
```
|
||||
|
||||
> In the case you do not want to use the assumed role credentials but the initial credentials to put the reports into the S3 bucket, use `-D`/`--output-bucket-no-assume` instead of `-B`/`--output-bucket.
|
||||
|
||||
> Make sure that the used credentials have s3:PutObject permissions in the S3 path where the reports are going to be uploaded.
|
||||
|
||||
## Output Formats
|
||||
|
||||
@@ -41,18 +31,63 @@ Prowler supports natively the following output formats:
|
||||
|
||||
- CSV
|
||||
- JSON
|
||||
- JSON-OCSF
|
||||
- JSON-ASFF
|
||||
- HTML
|
||||
|
||||
Hereunder is the structure for each of the supported report formats by Prowler:
|
||||
|
||||
### HTML
|
||||

|
||||
### CSV
|
||||
| ASSESSMENT_START_TIME | FINDING_UNIQUE_ID | PROVIDER | PROFILE | ACCOUNT_ID | ACCOUNT_NAME | ACCOUNT_EMAIL | ACCOUNT_ARN | ACCOUNT_ORG | ACCOUNT_TAGS | REGION | CHECK_ID | CHECK_TITLE | CHECK_TYPE | STATUS | STATUS_EXTENDED | SERVICE_NAME | SUBSERVICE_NAME | SEVERITY | RESOURCE_ID | RESOURCE_ARN | RESOURCE_TYPE | RESOURCE_DETAILS | RESOURCE_TAGS | DESCRIPTION | RISK | RELATED_URL | REMEDIATION_RECOMMENDATION_TEXT | REMEDIATION_RECOMMENDATION_URL | REMEDIATION_RECOMMENDATION_CODE_NATIVEIAC | REMEDIATION_RECOMMENDATION_CODE_TERRAFORM | REMEDIATION_RECOMMENDATION_CODE_CLI | REMEDIATION_RECOMMENDATION_CODE_OTHER | CATEGORIES | DEPENDS_ON | RELATED_TO | NOTES |
|
||||
| ------- | ----------- | ------ | -------- | ------------ | ----------- | ---------- | ---------- | --------------------- | -------------------------- | -------------- | ----------------- | ------------------------ | --------------- | ---------- | ----------------- | --------- | -------------- | ----------------- | ------------------ | --------------------- | -------------------- | ------------------- | ------------------- | -------------------- | -------------------- | -------------------- | -------------------- | -------------------- | -------------------- | -------------------- | -------------------- | -------------------- | -------------------- | -------------------- | -------------------- | -------------------- |
|
||||
|
||||
The following are the columns present in the CSV format:
|
||||
|
||||
- ASSESSMENT_START_TIME
|
||||
- FINDING_UNIQUE_ID
|
||||
- PROVIDER
|
||||
- PROFILE
|
||||
- ACCOUNT_ID
|
||||
- ACCOUNT_NAME
|
||||
- ACCOUNT_EMAIL
|
||||
- ACCOUNT_ARN
|
||||
- ACCOUNT_ORG
|
||||
- ACCOUNT_TAGS
|
||||
- REGION
|
||||
- CHECK_ID
|
||||
- CHECK_TITLE
|
||||
- CHECK_TYPE
|
||||
- STATUS
|
||||
- STATUS_EXTENDED
|
||||
- SERVICE_NAME
|
||||
- SUBSERVICE_NAME
|
||||
- SEVERITY
|
||||
- RESOURCE_ID
|
||||
- RESOURCE_ARN
|
||||
- RESOURCE_TYPE
|
||||
- RESOURCE_DETAILS
|
||||
- RESOURCE_TAGS
|
||||
- DESCRIPTION
|
||||
- COMPLIANCE
|
||||
- RISK
|
||||
- RELATED_URL
|
||||
- REMEDIATION_RECOMMENDATION_TEXT
|
||||
- REMEDIATION_RECOMMENDATION_URL
|
||||
- REMEDIATION_RECOMMENDATION_CODE_NATIVEIAC
|
||||
- REMEDIATION_RECOMMENDATION_CODE_TERRAFORM
|
||||
- REMEDIATION_RECOMMENDATION_CODE_CLI
|
||||
- REMEDIATION_RECOMMENDATION_CODE_OTHER
|
||||
- CATEGORIES
|
||||
- DEPENDS_ON
|
||||
- RELATED_TO
|
||||
- NOTES
|
||||
|
||||
> Since Prowler v3 the CSV column delimiter is the semicolon (`;`)
|
||||
### JSON
|
||||
|
||||
```
|
||||
The following code is an example output of the JSON format:
|
||||
|
||||
```json
|
||||
[{
|
||||
"AssessmentStartTime": "2022-12-01T14:16:57.354413",
|
||||
"FindingUniqueId": "",
|
||||
@@ -71,6 +106,10 @@ Hereunder is the structure for each of the supported report formats by Prowler:
|
||||
"Severity": "low",
|
||||
"ResourceId": "rds-instance-id",
|
||||
"ResourceArn": "",
|
||||
"ResourceTags": {
|
||||
"test": "test",
|
||||
"enironment": "dev"
|
||||
},
|
||||
"ResourceType": "AwsRdsDbInstance",
|
||||
"ResourceDetails": "",
|
||||
"Description": "Ensure RDS instances have minor version upgrade enabled.",
|
||||
@@ -89,8 +128,17 @@ Hereunder is the structure for each of the supported report formats by Prowler:
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Notes": ""
|
||||
},{
|
||||
"Notes": "",
|
||||
"Compliance": {
|
||||
"CIS-1.4": [
|
||||
"1.20"
|
||||
],
|
||||
"CIS-1.5": [
|
||||
"1.20"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"AssessmentStartTime": "2022-12-01T14:16:57.354413",
|
||||
"FindingUniqueId": "",
|
||||
"Provider": "aws",
|
||||
@@ -109,7 +157,7 @@ Hereunder is the structure for each of the supported report formats by Prowler:
|
||||
"ResourceId": "rds-instance-id",
|
||||
"ResourceArn": "",
|
||||
"ResourceType": "AwsRdsDbInstance",
|
||||
"ResourceDetails": "",
|
||||
"ResourceTags": {},
|
||||
"Description": "Ensure RDS instances have minor version upgrade enabled.",
|
||||
"Risk": "Auto Minor Version Upgrade is a feature that you can enable to have your database automatically upgraded when a new minor database engine version is available. Minor version upgrades often patch security vulnerabilities and fix bugs and therefore should be applied.",
|
||||
"RelatedUrl": "https://aws.amazon.com/blogs/database/best-practices-for-upgrading-amazon-rds-to-major-and-minor-versions-of-postgresql/",
|
||||
@@ -126,15 +174,278 @@ Hereunder is the structure for each of the supported report formats by Prowler:
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Notes": ""
|
||||
"Notes": "",
|
||||
"Compliance": {}
|
||||
}]
|
||||
```
|
||||
|
||||
> NOTE: Each finding is a `json` object within a list. This has changed in v3 since in v2 the format used was [ndjson](http://ndjson.org/).
|
||||
|
||||
|
||||
### JSON-OCSF
|
||||
|
||||
Based on [Open Cybersecurity Schema Framework Security Finding v1.0.0-rc.3](https://schema.ocsf.io/1.0.0-rc.3/classes/security_finding?extensions=)
|
||||
|
||||
```json
|
||||
[{
|
||||
"finding": {
|
||||
"title": "Check if ACM Certificates are about to expire in specific days or less",
|
||||
"desc": "Check if ACM Certificates are about to expire in specific days or less",
|
||||
"supporting_data": {
|
||||
"Risk": "Expired certificates can impact service availability.",
|
||||
"Notes": ""
|
||||
},
|
||||
"remediation": {
|
||||
"kb_articles": [
|
||||
"https://docs.aws.amazon.com/config/latest/developerguide/acm-certificate-expiration-check.html"
|
||||
],
|
||||
"desc": "Monitor certificate expiration and take automated action to renew; replace or remove. Having shorter TTL for any security artifact is a general recommendation; but requires additional automation in place. If not longer required delete certificate. Use AWS config using the managed rule: acm-certificate-expiration-check."
|
||||
},
|
||||
"types": [
|
||||
"Data Protection"
|
||||
],
|
||||
"src_url": "https://docs.aws.amazon.com/config/latest/developerguide/acm-certificate-expiration-check.html",
|
||||
"uid": "prowler-aws-acm_certificates_expiration_check-012345678912-eu-west-1-*.xxxxxxxxxxxxxx",
|
||||
"related_events": []
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"group": {
|
||||
"name": "acm"
|
||||
},
|
||||
"region": "eu-west-1",
|
||||
"name": "xxxxxxxxxxxxxx",
|
||||
"uid": "arn:aws:acm:eu-west-1:012345678912:certificate/xxxxxxxxxxxxxx",
|
||||
"labels": [
|
||||
{
|
||||
"Key": "project",
|
||||
"Value": "prowler-pro"
|
||||
},
|
||||
{
|
||||
"Key": "environment",
|
||||
"Value": "dev"
|
||||
},
|
||||
{
|
||||
"Key": "terraform",
|
||||
"Value": "true"
|
||||
},
|
||||
{
|
||||
"Key": "terraform_state",
|
||||
"Value": "aws"
|
||||
}
|
||||
],
|
||||
"type": "AwsCertificateManagerCertificate",
|
||||
"details": ""
|
||||
}
|
||||
],
|
||||
"status_detail": "ACM Certificate for xxxxxxxxxxxxxx expires in 111 days.",
|
||||
"compliance": {
|
||||
"status": "Success",
|
||||
"requirements": [
|
||||
"CISA: ['your-data-2']",
|
||||
"SOC2: ['cc_6_7']",
|
||||
"MITRE-ATTACK: ['T1040']",
|
||||
"GDPR: ['article_32']",
|
||||
"HIPAA: ['164_308_a_4_ii_a', '164_312_e_1']",
|
||||
"AWS-Well-Architected-Framework-Security-Pillar: ['SEC09-BP01']",
|
||||
"NIST-800-171-Revision-2: ['3_13_1', '3_13_2', '3_13_8', '3_13_11']",
|
||||
"NIST-800-53-Revision-4: ['ac_4', 'ac_17_2', 'sc_12']",
|
||||
"NIST-800-53-Revision-5: ['sc_7_12', 'sc_7_16']",
|
||||
"NIST-CSF-1.1: ['ac_5', 'ds_2']",
|
||||
"RBI-Cyber-Security-Framework: ['annex_i_1_3']",
|
||||
"FFIEC: ['d3-pc-im-b-1']",
|
||||
"FedRamp-Moderate-Revision-4: ['ac-4', 'ac-17-2', 'sc-12']",
|
||||
"FedRAMP-Low-Revision-4: ['ac-17', 'sc-12']"
|
||||
],
|
||||
"status_detail": "ACM Certificate for xxxxxxxxxxxxxx expires in 111 days."
|
||||
},
|
||||
"message": "ACM Certificate for xxxxxxxxxxxxxx expires in 111 days.",
|
||||
"severity_id": 4,
|
||||
"severity": "High",
|
||||
"cloud": {
|
||||
"account": {
|
||||
"name": "",
|
||||
"uid": "012345678912"
|
||||
},
|
||||
"region": "eu-west-1",
|
||||
"org": {
|
||||
"uid": "",
|
||||
"name": ""
|
||||
},
|
||||
"provider": "aws",
|
||||
"project_uid": ""
|
||||
},
|
||||
"time": "2023-06-30 10:28:55.297615",
|
||||
"metadata": {
|
||||
"original_time": "2023-06-30T10:28:55.297615",
|
||||
"profiles": [
|
||||
"dev"
|
||||
],
|
||||
"product": {
|
||||
"language": "en",
|
||||
"name": "Prowler",
|
||||
"version": "3.6.1",
|
||||
"vendor_name": "Prowler/ProwlerPro",
|
||||
"feature": {
|
||||
"name": "acm_certificates_expiration_check",
|
||||
"uid": "acm_certificates_expiration_check",
|
||||
"version": "3.6.1"
|
||||
}
|
||||
},
|
||||
"version": "1.0.0-rc.3"
|
||||
},
|
||||
"state_id": 0,
|
||||
"state": "New",
|
||||
"status_id": 1,
|
||||
"status": "Success",
|
||||
"type_uid": 200101,
|
||||
"type_name": "Security Finding: Create",
|
||||
"impact_id": 0,
|
||||
"impact": "Unknown",
|
||||
"confidence_id": 0,
|
||||
"confidence": "Unknown",
|
||||
"activity_id": 1,
|
||||
"activity_name": "Create",
|
||||
"category_uid": 2,
|
||||
"category_name": "Findings",
|
||||
"class_uid": 2001,
|
||||
"class_name": "Security Finding"
|
||||
},{
|
||||
"finding": {
|
||||
"title": "Check if ACM Certificates are about to expire in specific days or less",
|
||||
"desc": "Check if ACM Certificates are about to expire in specific days or less",
|
||||
"supporting_data": {
|
||||
"Risk": "Expired certificates can impact service availability.",
|
||||
"Notes": ""
|
||||
},
|
||||
"remediation": {
|
||||
"kb_articles": [
|
||||
"https://docs.aws.amazon.com/config/latest/developerguide/acm-certificate-expiration-check.html"
|
||||
],
|
||||
"desc": "Monitor certificate expiration and take automated action to renew; replace or remove. Having shorter TTL for any security artifact is a general recommendation; but requires additional automation in place. If not longer required delete certificate. Use AWS config using the managed rule: acm-certificate-expiration-check."
|
||||
},
|
||||
"types": [
|
||||
"Data Protection"
|
||||
],
|
||||
"src_url": "https://docs.aws.amazon.com/config/latest/developerguide/acm-certificate-expiration-check.html",
|
||||
"uid": "prowler-aws-acm_certificates_expiration_check-012345678912-eu-west-1-xxxxxxxxxxxxx",
|
||||
"related_events": []
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"group": {
|
||||
"name": "acm"
|
||||
},
|
||||
"region": "eu-west-1",
|
||||
"name": "xxxxxxxxxxxxx",
|
||||
"uid": "arn:aws:acm:eu-west-1:012345678912:certificate/3ea965a0-368d-4d13-95eb-5042a994edc4",
|
||||
"labels": [
|
||||
{
|
||||
"Key": "name",
|
||||
"Value": "prowler-pro-saas-dev-acm-internal-wildcard"
|
||||
},
|
||||
{
|
||||
"Key": "project",
|
||||
"Value": "prowler-pro-saas"
|
||||
},
|
||||
{
|
||||
"Key": "environment",
|
||||
"Value": "dev"
|
||||
},
|
||||
{
|
||||
"Key": "terraform",
|
||||
"Value": "true"
|
||||
},
|
||||
{
|
||||
"Key": "terraform_state",
|
||||
"Value": "aws/saas/base"
|
||||
}
|
||||
],
|
||||
"type": "AwsCertificateManagerCertificate",
|
||||
"details": ""
|
||||
}
|
||||
],
|
||||
"status_detail": "ACM Certificate for xxxxxxxxxxxxx expires in 119 days.",
|
||||
"compliance": {
|
||||
"status": "Success",
|
||||
"requirements": [
|
||||
"CISA: ['your-data-2']",
|
||||
"SOC2: ['cc_6_7']",
|
||||
"MITRE-ATTACK: ['T1040']",
|
||||
"GDPR: ['article_32']",
|
||||
"HIPAA: ['164_308_a_4_ii_a', '164_312_e_1']",
|
||||
"AWS-Well-Architected-Framework-Security-Pillar: ['SEC09-BP01']",
|
||||
"NIST-800-171-Revision-2: ['3_13_1', '3_13_2', '3_13_8', '3_13_11']",
|
||||
"NIST-800-53-Revision-4: ['ac_4', 'ac_17_2', 'sc_12']",
|
||||
"NIST-800-53-Revision-5: ['sc_7_12', 'sc_7_16']",
|
||||
"NIST-CSF-1.1: ['ac_5', 'ds_2']",
|
||||
"RBI-Cyber-Security-Framework: ['annex_i_1_3']",
|
||||
"FFIEC: ['d3-pc-im-b-1']",
|
||||
"FedRamp-Moderate-Revision-4: ['ac-4', 'ac-17-2', 'sc-12']",
|
||||
"FedRAMP-Low-Revision-4: ['ac-17', 'sc-12']"
|
||||
],
|
||||
"status_detail": "ACM Certificate for xxxxxxxxxxxxx expires in 119 days."
|
||||
},
|
||||
"message": "ACM Certificate for xxxxxxxxxxxxx expires in 119 days.",
|
||||
"severity_id": 4,
|
||||
"severity": "High",
|
||||
"cloud": {
|
||||
"account": {
|
||||
"name": "",
|
||||
"uid": "012345678912"
|
||||
},
|
||||
"region": "eu-west-1",
|
||||
"org": {
|
||||
"uid": "",
|
||||
"name": ""
|
||||
},
|
||||
"provider": "aws",
|
||||
"project_uid": ""
|
||||
},
|
||||
"time": "2023-06-30 10:28:55.297615",
|
||||
"metadata": {
|
||||
"original_time": "2023-06-30T10:28:55.297615",
|
||||
"profiles": [
|
||||
"dev"
|
||||
],
|
||||
"product": {
|
||||
"language": "en",
|
||||
"name": "Prowler",
|
||||
"version": "3.6.1",
|
||||
"vendor_name": "Prowler/ProwlerPro",
|
||||
"feature": {
|
||||
"name": "acm_certificates_expiration_check",
|
||||
"uid": "acm_certificates_expiration_check",
|
||||
"version": "3.6.1"
|
||||
}
|
||||
},
|
||||
"version": "1.0.0-rc.3"
|
||||
},
|
||||
"state_id": 0,
|
||||
"state": "New",
|
||||
"status_id": 1,
|
||||
"status": "Success",
|
||||
"type_uid": 200101,
|
||||
"type_name": "Security Finding: Create",
|
||||
"impact_id": 0,
|
||||
"impact": "Unknown",
|
||||
"confidence_id": 0,
|
||||
"confidence": "Unknown",
|
||||
"activity_id": 1,
|
||||
"activity_name": "Create",
|
||||
"category_uid": 2,
|
||||
"category_name": "Findings",
|
||||
"class_uid": 2001,
|
||||
"class_name": "Security Finding"
|
||||
}]
|
||||
```
|
||||
|
||||
> NOTE: Each finding is a `json` object.
|
||||
|
||||
### JSON-ASFF
|
||||
|
||||
```
|
||||
The following code is an example output of the [JSON-ASFF](https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-findings-format-syntax.html) format:
|
||||
|
||||
```json
|
||||
[{
|
||||
"SchemaVersion": "2018-10-08",
|
||||
"Id": "prowler-rds_instance_minor_version_upgrade_enabled-ACCOUNT_ID-eu-west-1-b1ade474a",
|
||||
@@ -166,7 +477,30 @@ Hereunder is the structure for each of the supported report formats by Prowler:
|
||||
],
|
||||
"Compliance": {
|
||||
"Status": "PASSED",
|
||||
"RelatedRequirements": []
|
||||
"RelatedRequirements": [
|
||||
"CISA your-systems-2 booting-up-thing-to-do-first-3",
|
||||
"CIS-1.5 2.3.2",
|
||||
"AWS-Foundational-Security-Best-Practices rds",
|
||||
"RBI-Cyber-Security-Framework annex_i_6",
|
||||
"FFIEC d3-cc-pm-b-1 d3-cc-pm-b-3"
|
||||
],
|
||||
"AssociatedStandards": [
|
||||
{
|
||||
"StandardsId": "CISA"
|
||||
},
|
||||
{
|
||||
"StandardsId": "CIS-1.5"
|
||||
},
|
||||
{
|
||||
"StandardsId": "AWS-Foundational-Security-Best-Practices"
|
||||
},
|
||||
{
|
||||
"StandardsId": "RBI-Cyber-Security-Framework"
|
||||
},
|
||||
{
|
||||
"StandardsId": "FFIEC"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Remediation": {
|
||||
"Recommendation": {
|
||||
@@ -205,7 +539,30 @@ Hereunder is the structure for each of the supported report formats by Prowler:
|
||||
],
|
||||
"Compliance": {
|
||||
"Status": "PASSED",
|
||||
"RelatedRequirements": []
|
||||
"RelatedRequirements": [
|
||||
"CISA your-systems-2 booting-up-thing-to-do-first-3",
|
||||
"CIS-1.5 2.3.2",
|
||||
"AWS-Foundational-Security-Best-Practices rds",
|
||||
"RBI-Cyber-Security-Framework annex_i_6",
|
||||
"FFIEC d3-cc-pm-b-1 d3-cc-pm-b-3"
|
||||
],
|
||||
"AssociatedStandards": [
|
||||
{
|
||||
"StandardsId": "CISA"
|
||||
},
|
||||
{
|
||||
"StandardsId": "CIS-1.5"
|
||||
},
|
||||
{
|
||||
"StandardsId": "AWS-Foundational-Security-Best-Practices"
|
||||
},
|
||||
{
|
||||
"StandardsId": "RBI-Cyber-Security-Framework"
|
||||
},
|
||||
{
|
||||
"StandardsId": "FFIEC"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Remediation": {
|
||||
"Recommendation": {
|
||||
@@ -216,4 +573,4 @@ Hereunder is the structure for each of the supported report formats by Prowler:
|
||||
}]
|
||||
```
|
||||
|
||||
> NOTE: Each finding is a `json` object.
|
||||
> NOTE: Each finding is a `json` object within a list.
|
||||
|
||||
21
mkdocs.yml
@@ -9,7 +9,7 @@ theme:
|
||||
language: en
|
||||
logo: img/prowler-logo.png
|
||||
name: material
|
||||
favicon: img/ProwlerPro-icon.svg
|
||||
favicon: img/prowler-icon.svg
|
||||
features:
|
||||
- navigation.tabs
|
||||
- navigation.tabs.sticky
|
||||
@@ -33,15 +33,20 @@ nav:
|
||||
- Reporting: tutorials/reporting.md
|
||||
- Compliance: tutorials/compliance.md
|
||||
- Quick Inventory: tutorials/quick-inventory.md
|
||||
- Slack Integration: tutorials/integrations.md
|
||||
- Configuration File: tutorials/configuration_file.md
|
||||
- Logging: tutorials/logging.md
|
||||
- Allowlist: tutorials/allowlist.md
|
||||
- Pentesting: tutorials/pentesting.md
|
||||
- Developer Guide: developer-guide/introduction.md
|
||||
- AWS:
|
||||
- Authentication: tutorials/aws/authentication.md
|
||||
- Assume Role: tutorials/aws/role-assumption.md
|
||||
- AWS Security Hub: tutorials/aws/securityhub.md
|
||||
- AWS Organizations: tutorials/aws/organizations.md
|
||||
- AWS Regions and Partitions: tutorials/aws/regions-and-partitions.md
|
||||
- Scan Multiple AWS Accounts: tutorials/aws/multiaccount.md
|
||||
- Send reports to AWS S3: tutorials/aws/s3.md
|
||||
- AWS CloudShell: tutorials/aws/cloudshell.md
|
||||
- Checks v2 to v3 Mapping: tutorials/aws/v2_to_v3_checks_mapping.md
|
||||
- Tag-based Scan: tutorials/aws/tag-based-scan.md
|
||||
@@ -50,6 +55,20 @@ nav:
|
||||
- Azure:
|
||||
- Authentication: tutorials/azure/authentication.md
|
||||
- Subscriptions: tutorials/azure/subscriptions.md
|
||||
- Google Cloud:
|
||||
- Authentication: tutorials/gcp/authentication.md
|
||||
- Developer Guide:
|
||||
- Introduction: developer-guide/introduction.md
|
||||
- Audit Info: developer-guide/audit-info.md
|
||||
- Services: developer-guide/services.md
|
||||
- Checks: developer-guide/checks.md
|
||||
- Documentation: developer-guide/documentation.md
|
||||
- Compliance: developer-guide/security-compliance-framework.md
|
||||
- Outputs: developer-guide/outputs.md
|
||||
- Integrations: developer-guide/integrations.md
|
||||
- Testing:
|
||||
- Unit Tests: developer-guide/unit-testing.md
|
||||
- Integration Tests: developer-guide/integration-testing.md
|
||||
- Security: security.md
|
||||
- Contact Us: contact.md
|
||||
- Troubleshooting: troubleshooting.md
|
||||
|
||||
@@ -4,7 +4,7 @@ AWSTemplateFormatVersion: '2010-09-09'
|
||||
# aws cloudformation create-stack \
|
||||
# --capabilities CAPABILITY_IAM --capabilities CAPABILITY_NAMED_IAM \
|
||||
# --template-body "file://create_role_to_assume_cfn.yaml" \
|
||||
# --stack-name "ProwlerExecRole" \
|
||||
# --stack-name "ProwlerScanRole" \
|
||||
# --parameters "ParameterKey=AuthorisedARN,ParameterValue=arn:aws:iam::123456789012:root"
|
||||
#
|
||||
Description: |
|
||||
@@ -13,7 +13,7 @@ Description: |
|
||||
account to assume that role. The role name and the ARN of the trusted user can all be passed
|
||||
to the CloudFormation stack as parameters. Then you can run Prowler to perform a security
|
||||
assessment with a command like:
|
||||
./prowler -A <THIS_ACCOUNT_ID> -R ProwlerExecRole
|
||||
prowler --role ProwlerScanRole.ARN
|
||||
Parameters:
|
||||
AuthorisedARN:
|
||||
Description: |
|
||||
@@ -22,12 +22,12 @@ Parameters:
|
||||
Type: String
|
||||
ProwlerRoleName:
|
||||
Description: |
|
||||
Name of the IAM role that will have these policies attached. Default: ProwlerExecRole
|
||||
Name of the IAM role that will have these policies attached. Default: ProwlerScanRole
|
||||
Type: String
|
||||
Default: 'ProwlerExecRole'
|
||||
Default: 'ProwlerScanRole'
|
||||
|
||||
Resources:
|
||||
ProwlerExecRole:
|
||||
ProwlerScanRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
AssumeRolePolicyDocument:
|
||||
@@ -42,31 +42,49 @@ Resources:
|
||||
# Bool:
|
||||
# 'aws:MultiFactorAuthPresent': true
|
||||
# This is 12h that is maximum allowed, Minimum is 3600 = 1h
|
||||
# to take advantage of this use -T like in './prowler -A <ACCOUNT_ID_TO_ASSUME> -R ProwlerExecRole -T 43200 -M text,html'
|
||||
# to take advantage of this use -T like in './prowler --role ProwlerScanRole.ARN -T 43200'
|
||||
MaxSessionDuration: 43200
|
||||
ManagedPolicyArns:
|
||||
- 'arn:aws:iam::aws:policy/SecurityAudit'
|
||||
- 'arn:aws:iam::aws:policy/job-function/ViewOnlyAccess'
|
||||
RoleName: !Sub ${ProwlerRoleName}
|
||||
Policies:
|
||||
- PolicyName: ProwlerExecRoleAdditionalViewPrivileges
|
||||
- PolicyName: ProwlerScanRoleAdditionalViewPrivileges
|
||||
PolicyDocument:
|
||||
Version : '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- 'ds:ListAuthorizedApplications'
|
||||
- 'account:Get*'
|
||||
- 'appstream:Describe*'
|
||||
- 'appstream:List*'
|
||||
- 'codeartifact:List*'
|
||||
- 'codebuild:BatchGet*'
|
||||
- 'ds:Get*'
|
||||
- 'ds:Describe*'
|
||||
- 'ds:List*'
|
||||
- 'ec2:GetEbsEncryptionByDefault'
|
||||
- 'ecr:Describe*'
|
||||
- 'elasticfilesystem:DescribeBackupPolicy'
|
||||
- 'glue:GetConnections'
|
||||
- 'glue:GetSecurityConfiguration'
|
||||
- 'glue:GetSecurityConfiguration*'
|
||||
- 'glue:SearchTables'
|
||||
- 'lambda:GetFunction'
|
||||
- 'lambda:GetFunction*'
|
||||
- 'macie2:GetMacieSession'
|
||||
- 's3:GetAccountPublicAccessBlock'
|
||||
- 'shield:DescribeProtection'
|
||||
- 'shield:GetSubscriptionState'
|
||||
- 'securityhub:BatchImportFindings'
|
||||
- 'securityhub:GetFindings'
|
||||
- 'ssm:GetDocument'
|
||||
- 'support:Describe*'
|
||||
- 'tag:GetTagKeys'
|
||||
Resource: '*'
|
||||
- PolicyName: ProwlerScanRoleAdditionalViewPrivilegesApiGateway
|
||||
PolicyDocument:
|
||||
Version : '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- 'apigateway:GET'
|
||||
Resource: 'arn:aws:apigateway:*::/restapis/*'
|
||||
|
||||
@@ -3,26 +3,37 @@
|
||||
"Statement": [
|
||||
{
|
||||
"Action": [
|
||||
"account:Get*",
|
||||
"appstream:Describe*",
|
||||
"appstream:List*",
|
||||
"backup:List*",
|
||||
"cloudtrail:GetInsightSelectors",
|
||||
"codeartifact:List*",
|
||||
"codebuild:BatchGet*",
|
||||
"ds:Describe*",
|
||||
"drs:Describe*",
|
||||
"ds:Get*",
|
||||
"ds:Describe*",
|
||||
"ds:List*",
|
||||
"ec2:GetEbsEncryptionByDefault",
|
||||
"ecr:Describe*",
|
||||
"ecr:GetRegistryScanningConfiguration",
|
||||
"elasticfilesystem:DescribeBackupPolicy",
|
||||
"glue:GetConnections",
|
||||
"glue:GetSecurityConfiguration*",
|
||||
"glue:SearchTables",
|
||||
"lambda:GetFunction*",
|
||||
"logs:FilterLogEvents",
|
||||
"macie2:GetMacieSession",
|
||||
"s3:GetAccountPublicAccessBlock",
|
||||
"shield:DescribeProtection",
|
||||
"shield:GetSubscriptionState",
|
||||
"securityhub:BatchImportFindings",
|
||||
"securityhub:GetFindings",
|
||||
"ssm:GetDocument",
|
||||
"ssm-incidents:List*",
|
||||
"support:Describe*",
|
||||
"tag:GetTagKeys"
|
||||
"tag:GetTagKeys",
|
||||
"wellarchitected:List*"
|
||||
],
|
||||
"Resource": "*",
|
||||
"Effect": "Allow",
|
||||
@@ -34,7 +45,8 @@
|
||||
"apigateway:GET"
|
||||
],
|
||||
"Resource": [
|
||||
"arn:aws:apigateway:*::/restapis/*"
|
||||
"arn:aws:apigateway:*::/restapis/*",
|
||||
"arn:aws:apigateway:*::/apis/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
3666
poetry.lock
generated
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from prowler.lib.banner import print_banner
|
||||
@@ -10,15 +11,16 @@ from prowler.lib.check.check import (
|
||||
exclude_checks_to_run,
|
||||
exclude_services_to_run,
|
||||
execute_checks,
|
||||
get_checks_from_input_arn,
|
||||
get_regions_from_audit_resources,
|
||||
list_categories,
|
||||
list_checks_json,
|
||||
list_services,
|
||||
parse_checks_from_folder,
|
||||
print_categories,
|
||||
print_checks,
|
||||
print_compliance_frameworks,
|
||||
print_compliance_requirements,
|
||||
print_services,
|
||||
remove_custom_checks_module,
|
||||
)
|
||||
from prowler.lib.check.checks_loader import load_checks_to_execute
|
||||
from prowler.lib.check.compliance import update_checks_metadata_with_compliance
|
||||
@@ -27,15 +29,20 @@ from prowler.lib.logger import logger, set_logging_config
|
||||
from prowler.lib.outputs.compliance import display_compliance_table
|
||||
from prowler.lib.outputs.html import add_html_footer, fill_html_overview_statistics
|
||||
from prowler.lib.outputs.json import close_json
|
||||
from prowler.lib.outputs.outputs import extract_findings_statistics, send_to_s3_bucket
|
||||
from prowler.lib.outputs.outputs import extract_findings_statistics
|
||||
from prowler.lib.outputs.slack import send_slack_message
|
||||
from prowler.lib.outputs.summary_table import display_summary_table
|
||||
from prowler.providers.aws.lib.allowlist.allowlist import parse_allowlist_file
|
||||
from prowler.providers.aws.lib.quick_inventory.quick_inventory import quick_inventory
|
||||
from prowler.providers.aws.lib.s3.s3 import send_to_s3_bucket
|
||||
from prowler.providers.aws.lib.security_hub.security_hub import (
|
||||
resolve_security_hub_previous_findings,
|
||||
)
|
||||
from prowler.providers.common.audit_info import set_provider_audit_info
|
||||
from prowler.providers.common.allowlist import set_provider_allowlist
|
||||
from prowler.providers.common.audit_info import (
|
||||
set_provider_audit_info,
|
||||
set_provider_execution_parameters,
|
||||
)
|
||||
from prowler.providers.common.outputs import set_provider_output_options
|
||||
from prowler.providers.common.quick_inventory import run_provider_quick_inventory
|
||||
|
||||
|
||||
def prowler():
|
||||
@@ -51,9 +58,13 @@ def prowler():
|
||||
services = args.services
|
||||
categories = args.categories
|
||||
checks_file = args.checks_file
|
||||
checks_folder = args.checks_folder
|
||||
severities = args.severity
|
||||
compliance_framework = args.compliance
|
||||
|
||||
if not args.no_banner:
|
||||
print_banner(args)
|
||||
|
||||
# We treat the compliance framework as another output format
|
||||
if compliance_framework:
|
||||
args.output_modes.extend(compliance_framework)
|
||||
@@ -61,9 +72,6 @@ def prowler():
|
||||
# Set Logger configuration
|
||||
set_logging_config(args.log_level, args.log_file, args.only_logs)
|
||||
|
||||
if not args.no_banner:
|
||||
print_banner(args)
|
||||
|
||||
if args.list_services:
|
||||
print_services(list_services(provider))
|
||||
sys.exit()
|
||||
@@ -73,33 +81,26 @@ def prowler():
|
||||
bulk_checks_metadata = bulk_load_checks_metadata(provider)
|
||||
|
||||
if args.list_categories:
|
||||
print_categories(list_categories(provider, bulk_checks_metadata))
|
||||
print_categories(list_categories(bulk_checks_metadata))
|
||||
sys.exit()
|
||||
|
||||
bulk_compliance_frameworks = {}
|
||||
# Load compliance frameworks
|
||||
logger.debug("Loading compliance frameworks from .json files")
|
||||
|
||||
# Load the compliance framework if specified with --compliance
|
||||
# If some compliance argument is specified we have to load it
|
||||
if (
|
||||
args.list_compliance
|
||||
or args.list_compliance_requirements
|
||||
or compliance_framework
|
||||
):
|
||||
bulk_compliance_frameworks = bulk_load_compliance_frameworks(provider)
|
||||
# Complete checks metadata with the compliance framework specification
|
||||
update_checks_metadata_with_compliance(
|
||||
bulk_compliance_frameworks, bulk_checks_metadata
|
||||
bulk_compliance_frameworks = bulk_load_compliance_frameworks(provider)
|
||||
# Complete checks metadata with the compliance framework specification
|
||||
update_checks_metadata_with_compliance(
|
||||
bulk_compliance_frameworks, bulk_checks_metadata
|
||||
)
|
||||
if args.list_compliance:
|
||||
print_compliance_frameworks(bulk_compliance_frameworks)
|
||||
sys.exit()
|
||||
if args.list_compliance_requirements:
|
||||
print_compliance_requirements(
|
||||
bulk_compliance_frameworks, args.list_compliance_requirements
|
||||
)
|
||||
if args.list_compliance:
|
||||
print_compliance_frameworks(bulk_compliance_frameworks)
|
||||
sys.exit()
|
||||
if args.list_compliance_requirements:
|
||||
print_compliance_requirements(
|
||||
bulk_compliance_frameworks, args.list_compliance_requirements
|
||||
)
|
||||
sys.exit()
|
||||
sys.exit()
|
||||
|
||||
# Load checks to execute
|
||||
checks_to_execute = load_checks_to_execute(
|
||||
@@ -114,6 +115,23 @@ def prowler():
|
||||
provider,
|
||||
)
|
||||
|
||||
# if --list-checks-json, dump a json file and exit
|
||||
if args.list_checks_json:
|
||||
print(list_checks_json(provider, sorted(checks_to_execute)))
|
||||
sys.exit()
|
||||
|
||||
# If -l/--list-checks passed as argument, print checks to execute and quit
|
||||
if args.list_checks:
|
||||
print_checks(provider, sorted(checks_to_execute), bulk_checks_metadata)
|
||||
sys.exit()
|
||||
|
||||
# Set the audit info based on the selected provider
|
||||
audit_info = set_provider_audit_info(provider, args.__dict__)
|
||||
|
||||
# Import custom checks from folder
|
||||
if checks_folder:
|
||||
parse_checks_from_folder(audit_info, checks_folder, provider)
|
||||
|
||||
# Exclude checks if -e/--excluded-checks
|
||||
if excluded_checks:
|
||||
checks_to_execute = exclude_checks_to_run(checks_to_execute, excluded_checks)
|
||||
@@ -124,40 +142,26 @@ def prowler():
|
||||
checks_to_execute, excluded_services, provider
|
||||
)
|
||||
|
||||
# Once the audit_info is set and we have the eventual checks based on the resource identifier,
|
||||
# it is time to check what Prowler's checks are going to be executed
|
||||
if audit_info.audit_resources:
|
||||
checks_from_resources = set_provider_execution_parameters(provider, audit_info)
|
||||
checks_to_execute = checks_to_execute.intersection(checks_from_resources)
|
||||
|
||||
# Sort final check list
|
||||
checks_to_execute = sorted(checks_to_execute)
|
||||
|
||||
# If -l/--list-checks passed as argument, print checks to execute and quit
|
||||
if args.list_checks:
|
||||
print_checks(provider, checks_to_execute, bulk_checks_metadata)
|
||||
sys.exit()
|
||||
# Parse Allowlist
|
||||
allowlist_file = set_provider_allowlist(provider, audit_info, args)
|
||||
|
||||
# Set the audit info based on the selected provider
|
||||
audit_info = set_provider_audit_info(provider, args.__dict__)
|
||||
|
||||
# Once the audit_info is set and we have the eventual checks from arn, it is time to exclude the others
|
||||
if audit_info.audit_resources:
|
||||
audit_info.audited_regions = get_regions_from_audit_resources(
|
||||
audit_info.audit_resources
|
||||
)
|
||||
checks_to_execute = get_checks_from_input_arn(
|
||||
audit_info.audit_resources, provider
|
||||
)
|
||||
|
||||
# Parse content from Allowlist file and get it, if necessary, from S3
|
||||
if provider == "aws" and args.allowlist_file:
|
||||
allowlist_file = parse_allowlist_file(audit_info, args.allowlist_file)
|
||||
else:
|
||||
allowlist_file = None
|
||||
|
||||
# Setting output options based on the selected provider
|
||||
# Set output options based on the selected provider
|
||||
audit_output_options = set_provider_output_options(
|
||||
provider, args, audit_info, allowlist_file, bulk_checks_metadata
|
||||
)
|
||||
|
||||
# Quick Inventory for AWS
|
||||
if provider == "aws" and args.quick_inventory:
|
||||
quick_inventory(audit_info, args.output_directory)
|
||||
# Run the quick inventory for the provider if available
|
||||
if hasattr(args, "quick_inventory") and args.quick_inventory:
|
||||
run_provider_quick_inventory(provider, audit_info, args)
|
||||
sys.exit()
|
||||
|
||||
# Execute checks
|
||||
@@ -174,10 +178,25 @@ def prowler():
|
||||
# Extract findings stats
|
||||
stats = extract_findings_statistics(findings)
|
||||
|
||||
if args.slack:
|
||||
if "SLACK_API_TOKEN" in os.environ and "SLACK_CHANNEL_ID" in os.environ:
|
||||
_ = send_slack_message(
|
||||
os.environ["SLACK_API_TOKEN"],
|
||||
os.environ["SLACK_CHANNEL_ID"],
|
||||
stats,
|
||||
provider,
|
||||
audit_info,
|
||||
)
|
||||
else:
|
||||
logger.critical(
|
||||
"Slack integration needs SLACK_API_TOKEN and SLACK_CHANNEL_ID environment variables (see more in https://docs.prowler.cloud/en/latest/tutorials/integrations/#slack)."
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
if args.output_modes:
|
||||
for mode in args.output_modes:
|
||||
# Close json file if exists
|
||||
if mode == "json" or mode == "json-asff":
|
||||
if "json" in mode:
|
||||
close_json(
|
||||
audit_output_options.output_filename, args.output_directory, mode
|
||||
)
|
||||
@@ -208,7 +227,11 @@ def prowler():
|
||||
|
||||
# Resolve previous fails of Security Hub
|
||||
if provider == "aws" and args.security_hub and not args.skip_sh_update:
|
||||
resolve_security_hub_previous_findings(args.output_directory, audit_info)
|
||||
resolve_security_hub_previous_findings(
|
||||
audit_output_options.output_directory,
|
||||
audit_output_options.output_filename,
|
||||
audit_info,
|
||||
)
|
||||
|
||||
# Display summary table
|
||||
if not args.only_logs:
|
||||
@@ -230,6 +253,10 @@ def prowler():
|
||||
audit_output_options.output_directory,
|
||||
)
|
||||
|
||||
# If custom checks were passed, remove the modules
|
||||
if checks_folder:
|
||||
remove_custom_checks_module(checks_folder, provider)
|
||||
|
||||
# If there are failed findings exit code 3, except if -z is input
|
||||
if not args.ignore_exit_code_3 and stats["total_fail"] > 0:
|
||||
sys.exit(3)
|
||||
|
||||
@@ -362,14 +362,15 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_rotate_access_key_90_days",
|
||||
"iam_no_root_access_key",
|
||||
"iam_user_mfa_enabled_console_access",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_disable_90_days_credentials",
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"Framework": "AWS-Well-Architected-Framework-Reliability-Pillar",
|
||||
"Version": "",
|
||||
"Provider": "AWS",
|
||||
"Description": "Best Practices for the AWS Well-Architected Framework Reliability Pillar encompasses the ability of a workload to perform its intended function correctly and consistently when it’s expected to. This includes the ability to operate and test the workload through its total lifecycle.",
|
||||
"Requirements": [
|
||||
{
|
||||
"Id": "REL09-BP03",
|
||||
"Description": "Configure backups to be taken automatically based on a periodic schedule informed by the Recovery Point Objective (RPO), or by changes in the dataset. Critical datasets with low data loss requirements need to be backed up automatically on a frequent basis, whereas less critical data where some loss is acceptable can be backed up less frequently.",
|
||||
"Attributes": [
|
||||
{
|
||||
"Name": "REL09-BP03 Perform data backup automatically",
|
||||
"WellArchitectedQuestionId": "backing-up-data",
|
||||
"WellArchitectedPracticeId": "rel_backing_up_data_automated_backups_data",
|
||||
"Section": "Failure management",
|
||||
"SubSection": "Backup up data",
|
||||
"LevelOfRisk": "High",
|
||||
"AssessmentMethod": "Automated",
|
||||
"Description": "Configure backups to be taken automatically based on a periodic schedule informed by the Recovery Point Objective (RPO), or by changes in the dataset. Critical datasets with low data loss requirements need to be backed up automatically on a frequent basis, whereas less critical data where some loss is acceptable can be backed up less frequently.",
|
||||
"ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_backing_up_data_automated_backups_data.html#implementation-guidance"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"cloudformation_stacks_termination_protection_enabled",
|
||||
"rds_instance_backup_enabled",
|
||||
"rds_instance_deletion_protection",
|
||||
"dynamodb_tables_pitr_enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "REL06-BP01",
|
||||
"Description": "Monitor components and services of AWS workload effectifely, using tools like Amazon CloudWatch and AWS Health Dashboard. Define relevant metrics, set thresholds, and analyze metrics and logs for early detection of issues.",
|
||||
"Attributes": [
|
||||
{
|
||||
"Name": "REL06-BP01 Monitor all components for the workload (Generation)",
|
||||
"WellArchitectedQuestionId": "monitor-aws-resources",
|
||||
"WellArchitectedPracticeId": "rel_monitor_aws_resources_monitor_resources",
|
||||
"Section": "Change management",
|
||||
"SubSection": "Monitor workload resources",
|
||||
"LevelOfRisk": "High",
|
||||
"AssessmentMethod": "Automated",
|
||||
"Description": "Monitor components and services of AWS workload effectifely, using tools like Amazon CloudWatch and AWS Health Dashboard. Define relevant metrics, set thresholds, and analyze metrics and logs for early detection of issues.",
|
||||
"ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_monitor_aws_resources_monitor_resources.html#implementation-guidance"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"apigateway_logging_enabled",
|
||||
"apigatewayv2_access_logging_enabled",
|
||||
"awslambda_function_invoke_api_operations_cloudtrail_logging_enabled",
|
||||
"cloudtrail_cloudwatch_logging_enabled",
|
||||
"elb_logging_enabled",
|
||||
"opensearch_service_domains_audit_logging_enabled",
|
||||
"opensearch_service_domains_cloudwatch_logging_enabled",
|
||||
"rds_instance_enhanced_monitoring_enabled",
|
||||
"rds_instance_integration_cloudwatch_logs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "REL10-BP01",
|
||||
"Description": "Distribute workload data and resources across multiple Availability Zones or, where necessary, across AWS Regions. These locations can be as diverse as required.",
|
||||
"Attributes": [
|
||||
{
|
||||
"Name": "REL10-BP01 Deploy the workload to multiple locations",
|
||||
"WellArchitectedQuestionId": "fault-isolation",
|
||||
"WellArchitectedPracticeId": "rel_fault_isolation_multiaz_region_system",
|
||||
"Section": "Failure management",
|
||||
"SubSection": "Use fault isolation to protect your workload",
|
||||
"LevelOfRisk": "High",
|
||||
"AssessmentMethod": "Automated",
|
||||
"Description": "Distribute workload data and resources across multiple Availability Zones or, where necessary, across AWS Regions. These locations can be as diverse as required.",
|
||||
"ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/use-fault-isolation-to-protect-your-workload.html#implementation-guidance."
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"rds_instance_multi_az"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -155,7 +155,8 @@
|
||||
"Id": "1.16",
|
||||
"Description": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not attached",
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges"
|
||||
],
|
||||
"Attributes": [
|
||||
{
|
||||
@@ -533,6 +534,7 @@
|
||||
"Id": "2.1.5",
|
||||
"Description": "Ensure that S3 Buckets are configured with 'Block public access (bucket settings)'",
|
||||
"Checks": [
|
||||
"s3_bucket_level_public_access_block",
|
||||
"s3_account_level_public_access_blocks"
|
||||
],
|
||||
"Attributes": [
|
||||
|
||||
@@ -155,7 +155,8 @@
|
||||
"Id": "1.16",
|
||||
"Description": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not attached",
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges"
|
||||
],
|
||||
"Attributes": [
|
||||
{
|
||||
@@ -533,6 +534,7 @@
|
||||
"Id": "2.1.5",
|
||||
"Description": "Ensure that S3 Buckets are configured with 'Block public access (bucket settings)'",
|
||||
"Checks": [
|
||||
"s3_bucket_level_public_access_block",
|
||||
"s3_account_level_public_access_blocks"
|
||||
],
|
||||
"Attributes": [
|
||||
|
||||
1379
prowler/compliance/aws/cis_2.0_aws.json
Normal file
@@ -88,7 +88,9 @@
|
||||
"iam_password_policy_symbol",
|
||||
"iam_password_policy_uppercase",
|
||||
"iam_no_custom_policy_permissive_role_assumption",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -181,7 +183,9 @@
|
||||
"Checks": [
|
||||
"elbv2_ssl_listeners",
|
||||
"iam_no_custom_policy_permissive_role_assumption",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -74,6 +74,30 @@
|
||||
"iam_support_role_created"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.acc.3.r2.aws.iam.1",
|
||||
"Description": "Privilegios de auditoría",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.acc.3.r2",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "control de acceso",
|
||||
"DescripcionControl": "Disponer de cuentas con privilegios de auditoría estrictamente controladas y personalizadas.",
|
||||
"Nivel": "opcional",
|
||||
"Tipo": "refuerzo",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_securityaudit_role_created"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.acc.4.aws.iam.1",
|
||||
"Description": "Proceso de gestión de derechos de acceso",
|
||||
@@ -103,7 +127,11 @@
|
||||
"awslambda_function_url_public",
|
||||
"awslambda_function_url_cors_policy",
|
||||
"iam_policy_allows_privilege_escalation",
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"organizations_scp_check_deny_regions",
|
||||
"organizations_account_part_of_organizations"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -129,7 +157,9 @@
|
||||
"Checks": [
|
||||
"iam_policy_allows_privilege_escalation",
|
||||
"iam_no_custom_policy_permissive_role_assumption",
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -202,7 +232,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -506,6 +538,31 @@
|
||||
"config_recorder_all_regions_enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.1.aws.cfg.2",
|
||||
"Description": "Inventario de activos",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.exp.1",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "explotación",
|
||||
"DescripcionControl": "Configurar una regla de Config Rules que alerte sobre el despliegue de recursos sin las etiquetas correspondientes asociadas.",
|
||||
"Nivel": "bajo",
|
||||
"Tipo": "recomendacion",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"config_recorder_all_regions_enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.1.aws.sys.1",
|
||||
"Description": "Inventario de activos",
|
||||
@@ -532,6 +589,81 @@
|
||||
"ssm_managed_compliant_patching"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.1.aws.sys.2",
|
||||
"Description": "Inventario de activos",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.exp.1",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "explotación",
|
||||
"DescripcionControl": "Asignar metadatos personalizados a cada nodo administrado con información sobre el responsable del activo.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "requisito",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"organizations_tags_policies_enabled_and_attached"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.1.aws.re.1",
|
||||
"Description": "Inventario de activos",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.exp.1",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "explotación",
|
||||
"DescripcionControl": "Se recomienda el uso de AWS Resource Explorer para la exploración de los recursos como instancias RDB, buckets S3o tablas de Amazon DynamoDB.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "recomendacion",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"resourceexplorer2_indexes_found"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.1.aws.tag.1",
|
||||
"Description": "Inventario de activos",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.exp.1",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "explotación",
|
||||
"DescripcionControl": "Para la correcta identificación del responsable, asociar etiquetas para todos los activos.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "requisito",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"organizations_tags_policies_enabled_and_attached"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.3.aws.cfg.1",
|
||||
"Description": "Gestión de la configuración de seguridad",
|
||||
@@ -633,6 +765,31 @@
|
||||
"ec2_instance_managed_by_ssm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.4.r4.aws.insp.1",
|
||||
"Description": "Monitorización continua",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.exp.4.r4",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "explotación",
|
||||
"DescripcionControl": "Desplegar a nivel de sistema una estrategia de monitorización continua de amenazas y vulnerabilidades detallando: indicadores críticos de seguridad, política de aplicación de parches y criterios de revisión regular y excepcional de amenazas del sistema.",
|
||||
"Nivel": "opcional",
|
||||
"Tipo": "refuerzo",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"inspector2_findings_exist"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.5.aws.ct.1",
|
||||
"Description": "Gestión de cambios",
|
||||
@@ -958,7 +1115,8 @@
|
||||
"Checks": [
|
||||
"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled",
|
||||
"cloudtrail_s3_dataevents_write_enabled",
|
||||
"cloudtrail_s3_dataevents_read_enabled"
|
||||
"cloudtrail_s3_dataevents_read_enabled",
|
||||
"cloudtrail_insights_exist"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1065,7 +1223,9 @@
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_allows_privilege_escalation",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_custom_policy_permissive_role_assumption",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_role_cross_service_confused_deputy_prevention"
|
||||
@@ -1094,6 +1254,27 @@
|
||||
"s3_bucket_policy_public_write_access"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.8.r4.aws.ct.3",
|
||||
"Description": "Control de acceso",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.exp.8.r4",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "explotación",
|
||||
"DescripcionControl": "Activar el acceso por MFA al registro de actividad almacenado en los buckets de Amazon S3 dedicados para AWS CloudTrail.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "refuerzo",
|
||||
"Dimensiones": [
|
||||
"trazabilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"cloudtrail_bucket_requires_mfa_delete"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.8.r4.aws.ct.4",
|
||||
"Description": "Control de acceso",
|
||||
@@ -1203,6 +1384,107 @@
|
||||
"cloudtrail_multi_region_enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.9.aws.img.1",
|
||||
"Description": "Registro de la gestión de incidentes",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.exp.9",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "explotación",
|
||||
"DescripcionControl": "Habilitar AWS Incident Manager y AWS CloudTrail en todas las regiones con el fin de recopilar información para generar contenido prescriptivo para la creación de informes exigidos por la medida de seguridad.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "recomendacion",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"ec2_instance_managed_by_ssm",
|
||||
"ssmincidents_enabled_with_plans"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.10.aws.tag.1",
|
||||
"Description": "Protección de claves criptográficas",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.exp.10",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "explotación",
|
||||
"DescripcionControl": "Se recomienda utilizar tags y alias para una mejor gestión y administración de las claves.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "recomendacion",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"organizations_tags_policies_enabled_and_attached"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.10.aws.cmk.1",
|
||||
"Description": "Protección de claves criptográficas",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.exp.10",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "explotación",
|
||||
"DescripcionControl": "Los usuarios o roles con privilegios para la creación de claves deben ser diferentes a los que van a utilizar las claves para operaciones de cifrado.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "requisito",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_full_access_to_kms"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.10.aws.cmk.2",
|
||||
"Description": "Protección de claves criptográficas",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.exp.10",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "explotación",
|
||||
"DescripcionControl": "Utilizar claves gestionadas por los clientes (CMK).",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "requisito",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_full_access_to_kms"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.exp.10.aws.cmk.3",
|
||||
"Description": "Protección de claves criptográficas",
|
||||
@@ -1378,6 +1660,31 @@
|
||||
"guardduty_is_enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.mon.1.aws.gd.3",
|
||||
"Description": "Detección de intrusión",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.mon.1",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "monitorización del sistema",
|
||||
"DescripcionControl": "Todas las cuentas miembro deberán estar añadidas para la supervisión bajo la cuenta raíz.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "medida",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"guardduty_centrally_managed"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.mon.2.aws.sh.1",
|
||||
"Description": "Sistema de métricas",
|
||||
@@ -1528,6 +1835,31 @@
|
||||
"securityhub_enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.mon.3.r2.aws.insp.1",
|
||||
"Description": "Análisis dinámico",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.mon.3.r2",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "monitorización del sistema",
|
||||
"DescripcionControl": "Utilizar la herramienta Inspector para la detección de posibles vulneerabilidades de las instancias EC2, las funciones Lambda y las imágenes de contenedor.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "refuerzo",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"inspector2_findings_exist"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.mon.3.r3.aws.gd.1",
|
||||
"Description": "Ciberamenazas avanzadas",
|
||||
@@ -1578,6 +1910,31 @@
|
||||
"config_recorder_all_regions_enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.mon.3.r6.aws.insp.1",
|
||||
"Description": "Inspecciones de seguridad",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.mon.3.r6",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "monitorización del sistema",
|
||||
"DescripcionControl": "Utilizar Config Rules y AWS Inspector.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "refuerzo",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"inspector2_findings_exist"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "mp.com.1.aws.sg.1",
|
||||
"Description": "Perímetro seguro",
|
||||
@@ -1626,7 +1983,7 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"ec2_securitygroup_in_use_without_ingress_filtering"
|
||||
"ec2_securitygroup_allow_ingress_from_internet_to_any_port"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1704,6 +2061,56 @@
|
||||
"elb_insecure_ssl_ciphers"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "mp.com.1.aws.nfw.1",
|
||||
"Description": "Perímetro seguro",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "mp.com.1",
|
||||
"Marco": "medidas de protección",
|
||||
"Categoria": "protección de las comunicaciones",
|
||||
"DescripcionControl": "Filtrar todo el tráfico entrante y saliente de la VPC a través de Firewalls de red.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "requisito",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"networkfirewall_in_all_vpc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "mp.com.1.aws.nfw.2",
|
||||
"Description": "Perímetro seguro",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "mp.com.1",
|
||||
"Marco": "medidas de protección",
|
||||
"Categoria": "protección de las comunicaciones",
|
||||
"DescripcionControl": "Incidir en la utilización de AWS Firewall Manager para gestionar los firewalls de forma centralizada.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "requisito",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"networkfirewall_in_all_vpc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "mp.com.1.aws.s3.1",
|
||||
"Description": "Perímetro seguro",
|
||||
@@ -1842,6 +2249,31 @@
|
||||
"cloudfront_distributions_https_enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "mp.com.4.aws.vpc.1",
|
||||
"Description": "Separación de flujos de información en la red",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "mp.com.4",
|
||||
"Marco": "medidas de protección",
|
||||
"Categoria": "protección de las comunicaciones",
|
||||
"DescripcionControl": "Los flujos de información de red se deben separar a través de la utilización de diferentes subnets.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "requisito",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"vpc_subnet_separate_private_public"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "mp.com.4.aws.vpc.2",
|
||||
"Description": "Separación de flujos de información en la red",
|
||||
@@ -1867,6 +2299,31 @@
|
||||
"ec2_instance_internet_facing_with_instance_profile"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "mp.com.4.r1.aws.vpc.1",
|
||||
"Description": "Segmentación lógica avanzada",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "mp.com.4.r1",
|
||||
"Marco": "medidas de protección",
|
||||
"Categoria": "protección de las comunicaciones",
|
||||
"DescripcionControl": "Implementar la segmentación a través de la utilización de diferentes VPCs.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "refuerzo",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad",
|
||||
"trazabilidad",
|
||||
"autenticidad",
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"vpc_subnet_separate_private_public"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "mp.com.4.r2.aws.vpc.1",
|
||||
"Description": "Segmentación lógica avanzada",
|
||||
@@ -1892,6 +2349,28 @@
|
||||
"vpc_peering_routing_tables_with_least_privilege"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "mp.com.4.r3.aws.vpc.1",
|
||||
"Description": "Segmentación física",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "mp.com.4.r3",
|
||||
"Marco": "medidas de protección",
|
||||
"Categoria": "protección de las comunicaciones",
|
||||
"DescripcionControl": "Implementar la segmentación a través de diferentes VPCs situadas en diferentes ubicaciones.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "refuerzo",
|
||||
"Dimensiones": [
|
||||
"confidencialidad",
|
||||
"integridad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"vpc_subnet_different_az"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "mp.si.2.aws.kms.1",
|
||||
"Description": "Criptografía",
|
||||
@@ -2183,7 +2662,7 @@
|
||||
"Dimensiones": [
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automáticoop.pl.2.aws.warch.1"
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
@@ -2195,6 +2674,27 @@
|
||||
"shield_advanced_protection_in_route53_hosted_zones"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "mp.s.4.aws.as.1",
|
||||
"Description": "Protección frente a la denegación de servicio ",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "mp.s.4",
|
||||
"Marco": "medidas de protección",
|
||||
"Categoria": "protección de los servicios",
|
||||
"DescripcionControl": "Activar la solución AWS Auto Scaling para dotar a los sistemas de la capacidad suficiente para atender la carga prevista con holgura y desplegar tecnologías para la prevención de ataques conocidos.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "requisito",
|
||||
"Dimensiones": [
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"autoscaling_group_multiple_az"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.pl.2.aws.warch.1",
|
||||
"Description": "Sistema de gestión",
|
||||
@@ -3461,6 +3961,27 @@
|
||||
],
|
||||
"Checks": []
|
||||
},
|
||||
{
|
||||
"Id": "op.cont.3.aws.drs.1",
|
||||
"Description": "Pruebas periódicas",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "op.cont.3",
|
||||
"Marco": "operacional",
|
||||
"Categoria": "continuidad del servicio",
|
||||
"DescripcionControl": "La organización puede hacer uso del servicio AWS Elastic Disaster Recovery, programando y ejecutando pruebas no disruptivas (simulacros que no afectan ni al servidor de origen ni a la replicación de datos en curso) que prueben el correcto funcionamiento de las recuperaciones del plan de continuidad.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "recomendacion",
|
||||
"Dimensiones": [
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"drs_job_exist"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "op.mon.1.aws.gd.4",
|
||||
"Description": "Detección de intrusión",
|
||||
@@ -3627,6 +4148,50 @@
|
||||
],
|
||||
"Checks": []
|
||||
},
|
||||
{
|
||||
"Id": "mp.info.6.aws.bcku.1",
|
||||
"Description": "Copias de seguridad",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "mp.info.6",
|
||||
"Marco": "medidas de protección",
|
||||
"Categoria": "protección de la información",
|
||||
"DescripcionControl": "Para los procedimientos de respaldo de cualquiera de los dos entornos (local y nube) y siempre y cuando se utilicen recursos compatibles en el entorno local, la entidad puede hacer uso de AWS Backup, que permite elaboración de planes de respaldo y la definición de reglas de frecuencia, ciclo de vida, lugar de almacenamiento y etiquetado de las copias de seguridad.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "recomendacion",
|
||||
"Dimensiones": [
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"backup_plans_exist",
|
||||
"backup_vaults_exist",
|
||||
"backup_reportplans_exist"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "mp.info.6.aws.tag.1",
|
||||
"Description": "Copias de seguridad",
|
||||
"Attributes": [
|
||||
{
|
||||
"IdGrupoControl": "mp.info.6",
|
||||
"Marco": "medidas de protección",
|
||||
"Categoria": "protección de la información",
|
||||
"DescripcionControl": "Los planes de respaldo se pueden integrar con AWS Tags, acotando con base en las etiquetas de los recursos el alcance de cada proceso de copiado.",
|
||||
"Nivel": "alto",
|
||||
"Tipo": "recomendacion",
|
||||
"Dimensiones": [
|
||||
"disponibilidad"
|
||||
],
|
||||
"ModoEjecucion": "automático"
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"organizations_tags_policies_enabled_and_attached"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "mp.info.6.r2.aws.bcku.1",
|
||||
"Description": "Protección de las copias de seguridad",
|
||||
|
||||
@@ -26,9 +26,10 @@
|
||||
"opensearch_service_domains_cloudwatch_logging_enabled",
|
||||
"guardduty_is_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -58,9 +59,10 @@
|
||||
"ec2_instance_public_ip",
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"emr_cluster_master_nodes_no_public_ip",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_disable_90_days_credentials",
|
||||
"awslambda_function_not_publicly_accessible",
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
"guardduty_is_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -91,9 +93,10 @@
|
||||
],
|
||||
"Checks": [
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -144,9 +147,10 @@
|
||||
],
|
||||
"Checks": [
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
"iam_rotate_access_key_90_days",
|
||||
@@ -188,9 +192,10 @@
|
||||
"ec2_instance_public_ip",
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"emr_cluster_master_nodes_no_public_ip",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_disable_90_days_credentials",
|
||||
"awslambda_function_not_publicly_accessible",
|
||||
@@ -249,9 +254,10 @@
|
||||
],
|
||||
"Checks": [
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_disable_90_days_credentials"
|
||||
]
|
||||
@@ -269,8 +275,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key"
|
||||
]
|
||||
},
|
||||
@@ -290,7 +297,9 @@
|
||||
"ec2_instance_public_ip",
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"emr_cluster_master_nodes_no_public_ip",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_disable_90_days_credentials",
|
||||
"awslambda_function_not_publicly_accessible",
|
||||
@@ -974,7 +983,9 @@
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -418,9 +418,10 @@
|
||||
],
|
||||
"Checks": [
|
||||
"ec2_instance_profile_attached",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key"
|
||||
]
|
||||
},
|
||||
@@ -519,8 +520,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -536,8 +538,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -553,8 +556,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key"
|
||||
@@ -579,8 +583,9 @@
|
||||
"iam_password_policy_number",
|
||||
"iam_password_policy_symbol",
|
||||
"iam_password_policy_uppercase",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_rotate_access_key_90_days",
|
||||
@@ -755,9 +760,10 @@
|
||||
"Checks": [
|
||||
"cloudtrail_multi_region_enabled",
|
||||
"cloudtrail_cloudwatch_logging_enabled",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -35,7 +35,9 @@
|
||||
"iam_password_policy_number",
|
||||
"iam_password_policy_symbol",
|
||||
"iam_password_policy_uppercase",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
|
||||
@@ -82,9 +82,10 @@
|
||||
"iam_password_policy_number",
|
||||
"iam_password_policy_symbol",
|
||||
"iam_password_policy_uppercase",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -166,9 +167,10 @@
|
||||
"iam_password_policy_number",
|
||||
"iam_password_policy_symbol",
|
||||
"iam_password_policy_uppercase",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
|
||||
@@ -45,7 +45,9 @@
|
||||
"elb_ssl_listeners",
|
||||
"emr_cluster_master_nodes_no_public_ip",
|
||||
"opensearch_service_domains_encryption_at_rest_enabled",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"awslambda_function_not_publicly_accessible",
|
||||
"awslambda_function_url_public",
|
||||
@@ -114,7 +116,9 @@
|
||||
"Checks": [
|
||||
"ec2_ebs_public_snapshot",
|
||||
"ec2_instance_public_ip",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"awslambda_function_not_publicly_accessible",
|
||||
"awslambda_function_url_public",
|
||||
@@ -169,7 +173,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_disable_90_days_credentials"
|
||||
]
|
||||
@@ -201,7 +207,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -255,7 +263,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -271,7 +281,9 @@
|
||||
],
|
||||
"Checks": [
|
||||
"iam_password_policy_reuse_24",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_rotate_access_key_90_days",
|
||||
"iam_disable_90_days_credentials",
|
||||
@@ -512,7 +524,9 @@
|
||||
"ec2_ebs_public_snapshot",
|
||||
"ec2_instance_public_ip",
|
||||
"emr_cluster_master_nodes_no_public_ip",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_user_mfa_enabled_console_access",
|
||||
"awslambda_function_not_publicly_accessible",
|
||||
"awslambda_function_url_public",
|
||||
|
||||
1273
prowler/compliance/aws/iso27001_2013_aws.json
Normal file
2088
prowler/compliance/aws/mitre_attack_aws.json
Normal file
@@ -21,7 +21,9 @@
|
||||
"ec2_instance_public_ip",
|
||||
"eks_endpoints_not_publicly_accessible",
|
||||
"emr_cluster_master_nodes_no_public_ip",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -60,7 +62,9 @@
|
||||
"ec2_instance_public_ip",
|
||||
"eks_endpoints_not_publicly_accessible",
|
||||
"emr_cluster_master_nodes_no_public_ip",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -125,7 +129,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_disable_90_days_credentials"
|
||||
]
|
||||
@@ -142,7 +148,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_disable_90_days_credentials"
|
||||
]
|
||||
@@ -159,7 +167,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key"
|
||||
]
|
||||
},
|
||||
@@ -175,7 +185,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key"
|
||||
]
|
||||
},
|
||||
@@ -449,7 +461,9 @@
|
||||
"ec2_ebs_public_snapshot",
|
||||
"ec2_instance_managed_by_ssm",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"awslambda_function_url_public",
|
||||
"rds_snapshots_public_access",
|
||||
@@ -821,7 +835,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -101,7 +101,9 @@
|
||||
"cloudtrail_cloudwatch_logging_enabled",
|
||||
"guardduty_is_enabled",
|
||||
"iam_password_policy_reuse_24",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
"iam_rotate_access_key_90_days",
|
||||
@@ -125,7 +127,9 @@
|
||||
],
|
||||
"Checks": [
|
||||
"ec2_ebs_public_snapshot",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_disable_90_days_credentials",
|
||||
"awslambda_function_url_public",
|
||||
@@ -180,7 +184,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -215,7 +221,9 @@
|
||||
"ec2_instance_public_ip",
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_disable_90_days_credentials",
|
||||
"awslambda_function_url_public",
|
||||
@@ -846,7 +854,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
"Checks": [
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -160,7 +162,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"emr_cluster_master_nodes_no_public_ip",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_disable_90_days_credentials",
|
||||
"awslambda_function_not_publicly_accessible",
|
||||
@@ -238,7 +242,9 @@
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -274,9 +280,10 @@
|
||||
"ec2_instance_public_ip",
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"emr_cluster_master_nodes_no_public_ip",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_disable_90_days_credentials",
|
||||
"awslambda_function_not_publicly_accessible",
|
||||
"awslambda_function_url_public",
|
||||
@@ -348,7 +355,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -376,7 +385,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -404,7 +415,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -432,7 +445,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -460,7 +475,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -488,7 +505,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -516,7 +535,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -544,7 +565,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -571,7 +594,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -599,7 +624,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -632,7 +659,9 @@
|
||||
"iam_no_root_access_key",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"ec2_instance_imdsv2_enabled"
|
||||
@@ -655,7 +684,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -683,7 +714,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -711,7 +744,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -741,7 +776,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"emr_cluster_master_nodes_no_public_ip",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_disable_90_days_credentials",
|
||||
"awslambda_function_not_publicly_accessible",
|
||||
@@ -771,7 +808,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -822,7 +861,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -866,7 +907,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -894,7 +937,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -922,7 +967,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -1046,7 +1093,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -1070,8 +1119,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1091,7 +1141,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"emr_cluster_master_nodes_no_public_ip",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_disable_90_days_credentials",
|
||||
"awslambda_function_not_publicly_accessible",
|
||||
@@ -1119,8 +1171,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key"
|
||||
]
|
||||
},
|
||||
@@ -1138,7 +1191,9 @@
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1177,8 +1232,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key"
|
||||
]
|
||||
},
|
||||
@@ -1432,7 +1488,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -2606,9 +2664,10 @@
|
||||
"ec2_instance_profile_attached",
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
"iam_rotate_access_key_90_days",
|
||||
@@ -2686,7 +2745,9 @@
|
||||
"ec2_instance_profile_attached",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -2941,7 +3002,9 @@
|
||||
"ec2_ebs_default_encryption",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -3912,7 +3975,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"emr_cluster_master_nodes_no_public_ip",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_disable_90_days_credentials",
|
||||
"awslambda_function_not_publicly_accessible",
|
||||
@@ -5383,7 +5448,9 @@
|
||||
"ec2_instance_imdsv2_enabled",
|
||||
"iam_password_policy_minimum_length_14",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_no_root_access_key",
|
||||
@@ -5426,7 +5493,9 @@
|
||||
"ec2_ebs_public_snapshot",
|
||||
"ec2_instance_public_ip",
|
||||
"emr_cluster_master_nodes_no_public_ip",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"awslambda_function_not_publicly_accessible",
|
||||
"awslambda_function_url_public",
|
||||
|
||||
@@ -569,7 +569,9 @@
|
||||
],
|
||||
"Checks": [
|
||||
"iam_password_policy_reuse_24",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_rotate_access_key_90_days",
|
||||
"iam_disable_90_days_credentials",
|
||||
@@ -624,7 +626,9 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"iam_disable_90_days_credentials"
|
||||
]
|
||||
@@ -1076,7 +1080,9 @@
|
||||
],
|
||||
"Checks": [
|
||||
"ec2_ebs_public_snapshot",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key",
|
||||
"awslambda_function_url_public",
|
||||
"rds_snapshots_public_access",
|
||||
|
||||
@@ -156,7 +156,9 @@
|
||||
],
|
||||
"Checks": [
|
||||
"iam_no_root_access_key",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_root_hardware_mfa_enabled",
|
||||
"iam_root_mfa_enabled",
|
||||
"iam_user_mfa_enabled_console_access",
|
||||
|
||||
@@ -113,9 +113,10 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_no_root_access_key"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
{
|
||||
"Id": "cc_1_1",
|
||||
"Name": "CC1.1 COSO Principle 1: The entity demonstrates a commitment to integrity and ethical values",
|
||||
"Description": "Sets the Tone at the Top - The board of directors and management, at all levels, demonstrate through their directives, actions, and behavior the importance of integrity and ethical values to support the functioning of the system of internal control.Establishes Standards of Conduct - The expectations of the board of directors and senior management concerning integrity and ethical values are defined in the entity’s standards of conduct and understood at all levels of the entity and by outsourced service providers and business partners. Evaluates Adherence to Standards of Conduct - Processes are in place to evaluate the performance of individuals and teams against the entity’s expected standards of conduct. Addresses Deviations in a Timely Manner - Deviations from the entity’s expected standards of conduct are identified and remedied in a timely and consistent manner.",
|
||||
"Description": "Sets the Tone at the Top - The board of directors and management, at all levels, demonstrate through their directives, actions, and behavior the importance of integrity and ethical values to support the functioning of the system of internal control. Establishes Standards of Conduct - The expectations of the board of directors and senior management concerning integrity and ethical values are defined in the entity’s standards of conduct and understood at all levels of the entity and by outsourced service providers and business partners. Evaluates Adherence to Standards of Conduct - Processes are in place to evaluate the performance of individuals and teams against the entity’s expected standards of conduct. Addresses Deviations in a Timely Manner - Deviations from the entity’s expected standards of conduct are identified and remedied in a timely and consistent manner.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_1_1",
|
||||
@@ -46,14 +46,16 @@
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_attached_only_to_group_or_roles",
|
||||
"iam_policy_no_administrative_privileges",
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges",
|
||||
"iam_disable_90_days_credentials"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "cc_1_4",
|
||||
"Name": "CC1.4 COSO Principle 4: The entity demonstrates a commitment to attract, develop, and retain competent individuals in alignment with objectives",
|
||||
"Description": "Establishes Policies and Practices - Policies and practices reflect expectations of competence necessary to support the achievement of objectives. Evaluates Competence and Addresses Shortcomings - The board of directors and management evaluate competence across the entity and in outsourced service providers in relation to established policies and practices and act as necessary to address shortcomings.Attracts, Develops, and Retains Individuals - The entity provides the mentoring and training needed to attract, develop, and retain sufficient and competent personnel and outsourced service providers to support the achievement of objectives.Plans and Prepares for Succession - Senior management and the board of directors develop contingency plans for assignments of responsibility important for internal control.Additional point of focus specifically related to all engagements using the trust services criteria:Considers the Background of Individuals - The entity considers the background of potential and existing personnel, contractors, and vendor employees when determining whether to employ and retain the individuals.Considers the Technical Competency of Individuals - The entity considers the technical competency of potential and existing personnel, contractors, and vendor employees when determining whether to employ and retain the individuals.Provides Training to Maintain Technical Competencies - The entity provides training programs, including continuing education and training, to ensure skill sets and technical competency of existing personnel, contractors, and vendor employees are developed and maintained.",
|
||||
"Description": "Establishes Policies and Practices - Policies and practices reflect expectations of competence necessary to support the achievement of objectives. Evaluates Competence and Addresses Shortcomings - The board of directors and management evaluate competence across the entity and in outsourced service providers in relation to established policies and practices and act as necessary to address shortcomings. Attracts, Develops, and Retains Individuals - The entity provides the mentoring and training needed to attract, develop, and retain sufficient and competent personnel and outsourced service providers to support the achievement of objectives. Plans and Prepares for Succession - Senior management and the board of directors develop contingency plans for assignments of responsibility important for internal control. Additional point of focus specifically related to all engagements using the trust services criteria: Considers the Background of Individuals - The entity considers the background of potential and existing personnel, contractors, and vendor employees when determining whether to employ and retain the individuals. Considers the Technical Competency of Individuals - The entity considers the technical competency of potential and existing personnel, contractors, and vendor employees when determining whether to employ and retain the individuals. Provides Training to Maintain Technical Competencies - The entity provides training programs, including continuing education and training, to ensure skill sets and technical competency of existing personnel, contractors, and vendor employees are developed and maintained.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_1_4",
|
||||
@@ -67,7 +69,7 @@
|
||||
{
|
||||
"Id": "cc_1_5",
|
||||
"Name": "CC1.5 COSO Principle 5: The entity holds individuals accountable for their internal control responsibilities in the pursuit of objectives",
|
||||
"Description": "Enforces Accountability Through Structures, Authorities, and Responsibilities - Management and the board of directors establish the mechanisms to communicate and hold individuals accountable for performance of internal control responsibilities across the entity and implement corrective action as necessary. Establishes Performance Measures, Incentives, and Rewards - Management and the board of directors establish performance measures, incentives, and other rewards appropriate for responsibilities at all levels of the entity, reflecting appropriate dimensions of performance and expected standards of conduct, and considering the achievement of both short-term and longer-term objectives.Evaluates Performance Measures, Incentives, and Rewards for Ongoing Relevance - Management and the board of directors align incentives and rewards with the fulfillment of internal control responsibilities in the achievement of objectives.Considers Excessive Pressures - Management and the board of directors evaluate and adjust pressures associated with the achievement of objectives as they assign responsibilities, develop performance measures, and evaluate performance. Evaluates Performance and Rewards or Disciplines Individuals - Management and the board of directors evaluate performance of internal control responsibilities, including adherence to standards of conduct and expected levels of competence, and provide rewards or exercise disciplinary action, as appropriate.",
|
||||
"Description": "Enforces Accountability Through Structures, Authorities, and Responsibilities - Management and the board of directors establish the mechanisms to communicate and hold individuals accountable for performance of internal control responsibilities across the entity and implement corrective action as necessary. Establishes Performance Measures, Incentives, and Rewards - Management and the board of directors establish performance measures, incentives, and other rewards appropriate for responsibilities at all levels of the entity, reflecting appropriate dimensions of performance and expected standards of conduct, and considering the achievement of both short-term and longer-term objectives. Evaluates Performance Measures, Incentives, and Rewards for Ongoing Relevance - Management and the board of directors align incentives and rewards with the fulfillment of internal control responsibilities in the achievement of objectives. Considers Excessive Pressures - Management and the board of directors evaluate and adjust pressures associated with the achievement of objectives as they assign responsibilities, develop performance measures, and evaluate performance. Evaluates Performance and Rewards or Disciplines Individuals - Management and the board of directors evaluate performance of internal control responsibilities, including adherence to standards of conduct and expected levels of competence, and provide rewards or exercise disciplinary action, as appropriate.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_1_5",
|
||||
@@ -128,7 +130,7 @@
|
||||
{
|
||||
"Id": "cc_3_1",
|
||||
"Name": "CC3.1 COSO Principle 6: The entity specifies objectives with sufficient clarity to enable the identification and assessment of risks relating to objectives",
|
||||
"Description": "Operations Ojectives:Reflects Management's Choices - Operations objectives reflect management's choices about structure, industry considerations, and performance of the entity.Considers Tolerances for Risk - Management considers the acceptable levels of variation relative to the achievement of operations objectives.External Financial Reporting Objectives:Complies With Applicable Accounting Standards - Financial reporting objectives are consistent with accounting principles suitable and available for that entity. The accounting principles selected are appropriate in the circumstances.External Nonfinancial Reporting Objectives:Complies With Externally Established Frameworks - Management establishes objectives consistent with laws and regulations or standards and frameworks of recognized external organizations.Reflects Entity Activities - External reporting reflects the underlying transactions and events within a range of acceptable limits.Considers the Required Level of Precision—Management reflects the required level of precision and accuracy suitable for user needs and based on criteria established by third parties in nonfinancial reporting.Internal Reporting Objectives:Reflects Management's Choices - Internal reporting provides management with accurate and complete information regarding management's choices and information needed in managing the entity.Considers the Required Level of Precision—Management reflects the required level of precision and accuracy suitable for user needs in nonfinancial reporting objectives and materiality within financial reporting objectives.Reflects Entity Activities—Internal reporting reflects the underlying transactions and events within a range of acceptable limits.Compliance Objectives:Reflects External Laws and Regulations - Laws and regulations establish minimum standards of conduct, which the entity integrates into compliance objectives.Considers Tolerances for Risk - Management considers the acceptable levels of variation relative to the achievement of operations objectives.Additional point of focus specifically related to all engagements using the trust services criteria: Establishes Sub-objectives to Support Objectives—Management identifies sub-objectives related to security, availability, processing integrity, confidentiality, and privacy to support the achievement of the entity’s objectives related to reporting, operations, and compliance.",
|
||||
"Description": "Operations Objectives: Reflects Management's Choices - Operations objectives reflect management's choices about structure, industry considerations, and performance of the entity. Considers Tolerances for Risk - Management considers the acceptable levels of variation relative to the achievement of operations objectives. External Financial Reporting Objectives: Complies With Applicable Accounting Standards - Financial reporting objectives are consistent with accounting principles suitable and available for that entity. The accounting principles selected are appropriate in the circumstances. External Nonfinancial Reporting Objectives: Complies With Externally Established Frameworks - Management establishes objectives consistent with laws and regulations or standards and frameworks of recognized external organizations. Reflects Entity Activities - External reporting reflects the underlying transactions and events within a range of acceptable limits. Considers the Required Level of Precision—Management reflects the required level of precision and accuracy suitable for user needs and based on criteria established by third parties in nonfinancial reporting. Internal Reporting Objectives: Reflects Management's Choices - Internal reporting provides management with accurate and complete information regarding management's choices and information needed in managing the entity. Considers the Required Level of Precision—Management reflects the required level of precision and accuracy suitable for user needs in nonfinancial reporting objectives and materiality within financial reporting objectives. Reflects Entity Activities—Internal reporting reflects the underlying transactions and events within a range of acceptable limits. Compliance Objectives: Reflects External Laws and Regulations - Laws and regulations establish minimum standards of conduct, which the entity integrates into compliance objectives. Considers Tolerances for Risk - Management considers the acceptable levels of variation relative to the achievement of operations objectives. Additional point of focus specifically related to all engagements using the trust services criteria: Establishes Sub-objectives to Support Objectives—Management identifies sub-objectives related to security, availability, processing integrity, confidentiality, and privacy to support the achievement of the entity’s objectives related to reporting, operations, and compliance.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_3_1",
|
||||
@@ -146,7 +148,7 @@
|
||||
{
|
||||
"Id": "cc_3_2",
|
||||
"Name": "CC3.2 COSO Principle 7: The entity identifies risks to the achievement of its objectives across the entity and analyzes risks as a basis for determining how the risks should be managed",
|
||||
"Description": "Includes Entity, Subsidiary, Division, Operating Unit, and Functional Levels - The entity identifies and assesses risk at the entity, subsidiary, division, operating unit, and functional levels relevant to the achievement of objectives.Analyzes Internal and External Factors - Risk identification considers both internal and external factors and their impact on the achievement of objectives.Involves Appropriate Levels of Management - The entity puts into place effective risk assessment mechanisms that involve appropriate levels of management.Estimates Significance of Risks Identified - Identified risks are analyzed through a process that includes estimating the potential significance of the risk.Determines How to Respond to Risks - Risk assessment includes considering how the risk should be managed and whether to accept, avoid, reduce, or share the risk.Additional points of focus specifically related to all engagements using the trust services criteria:Identifies and Assesses Criticality of Information Assets and Identifies Threats and Vulnerabilities - The entity's risk identification and assessment process includes (1) identifying information assets, including physical devices and systems, virtual devices, software, data and data flows, external information systems, and organizational roles; (2) assessing the criticality of those information assets; (3) identifying the threats to the assets from intentional (including malicious) and unintentional acts and environmental events; and (4) identifying the vulnerabilities of the identified assets.",
|
||||
"Description": "Includes Entity, Subsidiary, Division, Operating Unit, and Functional Levels - The entity identifies and assesses risk at the entity, subsidiary, division, operating unit, and functional levels relevant to the achievement of objectives. Analyzes Internal and External Factors - Risk identification considers both internal and external factors and their impact on the achievement of objectives. Involves Appropriate Levels of Management - The entity puts into place effective risk assessment mechanisms that involve appropriate levels of management. Estimates Significance of Risks Identified - Identified risks are analyzed through a process that includes estimating the potential significance of the risk. Determines How to Respond to Risks - Risk assessment includes considering how the risk should be managed and whether to accept, avoid, reduce, or share the risk. Additional points of focus specifically related to all engagements using the trust services criteria: Identifies and Assesses Criticality of Information Assets and Identifies Threats and Vulnerabilities - The entity's risk identification and assessment process includes (1) identifying information assets, including physical devices and systems, virtual devices, software, data and data flows, external information systems, and organizational roles; (2) assessing the criticality of those information assets; (3) identifying the threats to the assets from intentional (including malicious) and unintentional acts and environmental events; and (4) identifying the vulnerabilities of the identified assets.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_3_2",
|
||||
@@ -166,7 +168,7 @@
|
||||
{
|
||||
"Id": "cc_3_3",
|
||||
"Name": "CC3.3 COSO Principle 8: The entity considers the potential for fraud in assessing risks to the achievement of objectives",
|
||||
"Description": "Considers Various Types of Fraud - The assessment of fraud considers fraudulent reporting, possible loss of assets, and corruption resulting from the various ways that fraud and misconduct can occur.Assesses Incentives and Pressures - The assessment of fraud risks considers incentives and pressures.Assesses Opportunities - The assessment of fraud risk considers opportunities for unauthorized acquisition,use, or disposal of assets, altering the entity’s reporting records, or committing other inappropriate acts.Assesses Attitudes and Rationalizations - The assessment of fraud risk considers how management and other personnel might engage in or justify inappropriate actions.Additional point of focus specifically related to all engagements using the trust services criteria: Considers the Risks Related to the Use of IT and Access to Information - The assessment of fraud risks includes consideration of threats and vulnerabilities that arise specifically from the use of IT and access to information.",
|
||||
"Description": "Considers Various Types of Fraud - The assessment of fraud considers fraudulent reporting, possible loss of assets, and corruption resulting from the various ways that fraud and misconduct can occur. Assesses Incentives and Pressures - The assessment of fraud risks considers incentives and pressures. Assesses Opportunities - The assessment of fraud risk considers opportunities for unauthorized acquisition,use, or disposal of assets, altering the entity’s reporting records, or committing other inappropriate acts. Assesses Attitudes and Rationalizations - The assessment of fraud risk considers how management and other personnel might engage in or justify inappropriate actions. Additional point of focus specifically related to all engagements using the trust services criteria: Considers the Risks Related to the Use of IT and Access to Information - The assessment of fraud risks includes consideration of threats and vulnerabilities that arise specifically from the use of IT and access to information.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_3_3",
|
||||
@@ -180,7 +182,7 @@
|
||||
{
|
||||
"Id": "cc_3_4",
|
||||
"Name": "CC3.4 COSO Principle 9: The entity identifies and assesses changes that could significantly impact the system of internal control",
|
||||
"Description": "Assesses Changes in the External Environment - The risk identification process considers changes to the regulatory, economic, and physical environment in which the entity operates.Assesses Changes in the Business Model - The entity considers the potential impacts of new business lines, dramatically altered compositions of existing business lines, acquired or divested business operations on the system of internal control, rapid growth, changing reliance on foreign geographies, and new technologies.Assesses Changes in Leadership - The entity considers changes in management and respective attitudes and philosophies on the system of internal control.Assess Changes in Systems and Technology - The risk identification process considers changes arising from changes in the entity’s systems and changes in the technology environment.Assess Changes in Vendor and Business Partner Relationships - The risk identification process considers changes in vendor and business partner relationships.",
|
||||
"Description": "Assesses Changes in the External Environment - The risk identification process considers changes to the regulatory, economic, and physical environment in which the entity operates. Assesses Changes in the Business Model - The entity considers the potential impacts of new business lines, dramatically altered compositions of existing business lines, acquired or divested business operations on the system of internal control, rapid growth, changing reliance on foreign geographies, and new technologies. Assesses Changes in Leadership - The entity considers changes in management and respective attitudes and philosophies on the system of internal control. Assess Changes in Systems and Technology - The risk identification process considers changes arising from changes in the entity’s systems and changes in the technology environment. Assess Changes in Vendor and Business Partner Relationships - The risk identification process considers changes in vendor and business partner relationships.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_3_4",
|
||||
@@ -196,7 +198,7 @@
|
||||
{
|
||||
"Id": "cc_4_1",
|
||||
"Name": "CC4.1 COSO Principle 16: The entity selects, develops, and performs ongoing and/or separate evaluations to ascertain whether the components of internal control are present and functioning",
|
||||
"Description": "Considers a Mix of Ongoing and Separate Evaluations - Management includes a balance of ongoing and separate evaluations.Considers Rate of Change - Management considers the rate of change in business and business processes when selecting and developing ongoing and separate evaluations.Establishes Baseline Understanding - The design and current state of an internal control system are used to establish a baseline for ongoing and separate evaluations.Uses Knowledgeable Personnel - Evaluators performing ongoing and separate evaluations have sufficient knowledge to understand what is being evaluated.Integrates With Business Processes - Ongoing evaluations are built into the business processes and adjust to changing conditions.Adjusts Scope and Frequency—Management varies the scope and frequency of separate evaluations depending on risk.Objectively Evaluates - Separate evaluations are performed periodically to provide objective feedback.Considers Different Types of Ongoing and Separate Evaluations - Management uses a variety of different types of ongoing and separate evaluations, including penetration testing, independent certification made against established specifications (for example, ISO certifications), and internal audit assessments.",
|
||||
"Description": "Considers a Mix of Ongoing and Separate Evaluations - Management includes a balance of ongoing and separate evaluations. Considers Rate of Change - Management considers the rate of change in business and business processes when selecting and developing ongoing and separate evaluations. Establishes Baseline Understanding - The design and current state of an internal control system are used to establish a baseline for ongoing and separate evaluations. Uses Knowledgeable Personnel - Evaluators performing ongoing and separate evaluations have sufficient knowledge to understand what is being evaluated. Integrates With Business Processes - Ongoing evaluations are built into the business processes and adjust to changing conditions. Adjusts Scope and Frequency—Management varies the scope and frequency of separate evaluations depending on risk. Objectively Evaluates - Separate evaluations are performed periodically to provide objective feedback. Considers Different Types of Ongoing and Separate Evaluations - Management uses a variety of different types of ongoing and separate evaluations, including penetration testing, independent certification made against established specifications (for example, ISO certifications), and internal audit assessments.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_4_1",
|
||||
@@ -210,7 +212,7 @@
|
||||
{
|
||||
"Id": "cc_4_2",
|
||||
"Name": "CC4.2 COSO Principle 17: The entity evaluates and communicates internal control deficiencies in a timely manner to those parties responsible for taking corrective action, including senior management and the board of directors, as appropriate",
|
||||
"Description": "Assesses Results - Management and the board of directors, as appropriate, assess results of ongoing and separate evaluations.Communicates Deficiencies - Deficiencies are communicated to parties responsible for taking corrective action and to senior management and the board of directors, as appropriate.Monitors Corrective Action - Management tracks whether deficiencies are remedied on a timely basis.",
|
||||
"Description": "Assesses Results - Management and the board of directors, as appropriate, assess results of ongoing and separate evaluations. Communicates Deficiencies - Deficiencies are communicated to parties responsible for taking corrective action and to senior management and the board of directors, as appropriate. Monitors Corrective Action - Management tracks whether deficiencies are remedied on a timely basis.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_4_2",
|
||||
@@ -227,7 +229,7 @@
|
||||
{
|
||||
"Id": "cc_5_1",
|
||||
"Name": "CC5.1 COSO Principle 10: The entity selects and develops control activities that contribute to the mitigation of risks to the achievement of objectives to acceptable levels",
|
||||
"Description": "Integrates With Risk Assessment - Control activities help ensure that risk responses that address and mitigate risks are carried out.Considers Entity-Specific Factors - Management considers how the environment, complexity, nature, and scope of its operations, as well as the specific characteristics of its organization, affect the selection and development of control activities.Determines Relevant Business Processes - Management determines which relevant business processes require control activities.Evaluates a Mix of 2017 Data Submitted Types - Control activities include a range and variety of controls and may include a balance of approaches to mitigate risks, considering both manual and automated controls, and preventive and detective controls.Considers at What Level Activities Are Applied - Management considers control activities at various levels in the entity.Addresses Segregation of Duties - Management segregates incompatible duties, and where such segregation is not practical, management selects and develops alternative control activities.",
|
||||
"Description": "Integrates With Risk Assessment - Control activities help ensure that risk responses that address and mitigate risks are carried out. Considers Entity-Specific Factors - Management considers how the environment, complexity, nature, and scope of its operations, as well as the specific characteristics of its organization, affect the selection and development of control activities. Determines Relevant Business Processes - Management determines which relevant business processes require control activities. Evaluates a Mix of 2017 Data Submitted Types - Control activities include a range and variety of controls and may include a balance of approaches to mitigate risks, considering both manual and automated controls, and preventive and detective controls. Considers at What Level Activities Are Applied - Management considers control activities at various levels in the entity. Addresses Segregation of Duties - Management segregates incompatible duties, and where such segregation is not practical, management selects and develops alternative control activities.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_5_1",
|
||||
@@ -241,7 +243,7 @@
|
||||
{
|
||||
"Id": "cc_5_2",
|
||||
"Name": "CC5.2 COSO Principle 11: The entity also selects and develops general control activities over technology to support the achievement of objectives",
|
||||
"Description": "Determines Dependency Between the Use of Technology in Business Processes and Technology General Controls - Management understands and determines the dependency and linkage between business processes, automated control activities, and technology general controls.Establishes Relevant Technology Infrastructure Control Activities - Management selects and develops control activities over the technology infrastructure, which are designed and implemented to help ensure the completeness, accuracy, and availability of technology processing.Establishes Relevant Security Management Process Controls Activities - Management selects and develops control activities that are designed and implemented to restrict technology access rights to authorized users commensurate with their job responsibilities and to protect the entity’s assets from external threats.Establishes Relevant Technology Acquisition, Development, and Maintenance Process Control Activities - Management selects and develops control activities over the acquisition, development, and maintenance of technology and its infrastructure to achieve management’s objectives.",
|
||||
"Description": "Determines Dependency Between the Use of Technology in Business Processes and Technology General Controls - Management understands and determines the dependency and linkage between business processes, automated control activities, and technology general controls. Establishes Relevant Technology Infrastructure Control Activities - Management selects and develops control activities over the technology infrastructure, which are designed and implemented to help ensure the completeness, accuracy, and availability of technology processing. Establishes Relevant Security Management Process Controls Activities - Management selects and develops control activities that are designed and implemented to restrict technology access rights to authorized users commensurate with their job responsibilities and to protect the entity’s assets from external threats. Establishes Relevant Technology Acquisition, Development, and Maintenance Process Control Activities - Management selects and develops control activities over the acquisition, development, and maintenance of technology and its infrastructure to achieve management’s objectives.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_5_2",
|
||||
@@ -255,7 +257,7 @@
|
||||
{
|
||||
"Id": "cc_5_3",
|
||||
"Name": "CCC5.3 COSO Principle 12: The entity deploys control activities through policies that establish what is expected and in procedures that put policies into action",
|
||||
"Description": "Establishes Policies and Procedures to Support Deployment of Management ‘s Directives - Management establishes control activities that are built into business processes and employees’ day-to-day activities through policies establishing what is expected and relevant procedures specifying actions.Establishes Responsibility and Accountability for Executing Policies and Procedures - Management establishes responsibility and accountability for control activities with management (or other designated personnel) of the business unit or function in which the relevant risks reside.Performs in a Timely Manner - Responsible personnel perform control activities in a timely manner as defined by the policies and procedures.Takes Corrective Action - Responsible personnel investigate and act on matters identified as a result of executing control activities.Performs Using Competent Personnel - Competent personnel with sufficient authority perform control activities with diligence and continuing focus.Reassesses Policies and Procedures - Management periodically reviews control activities to determine their continued relevance and refreshes them when necessary.",
|
||||
"Description": "Establishes Policies and Procedures to Support Deployment of Management ‘s Directives - Management establishes control activities that are built into business processes and employees’ day-to-day activities through policies establishing what is expected and relevant procedures specifying actions. Establishes Responsibility and Accountability for Executing Policies and Procedures - Management establishes responsibility and accountability for control activities with management (or other designated personnel) of the business unit or function in which the relevant risks reside. Performs in a Timely Manner - Responsible personnel perform control activities in a timely manner as defined by the policies and procedures. Takes Corrective Action - Responsible personnel investigate and act on matters identified as a result of executing control activities. Performs Using Competent Personnel - Competent personnel with sufficient authority perform control activities with diligence and continuing focus. Reassesses Policies and Procedures - Management periodically reviews control activities to determine their continued relevance and refreshes them when necessary.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_5_3",
|
||||
@@ -269,7 +271,7 @@
|
||||
{
|
||||
"Id": "cc_6_1",
|
||||
"Name": "CC6.1 The entity implements logical access security software, infrastructure, and architectures over protected information assets to protect them from security events to meet the entity's objectives",
|
||||
"Description": "Identifies and Manages the Inventory of Information Assets - The entity identifies, inventories, classifies, and manages information assets.Restricts Logical Access - Logical access to information assets, including hardware, data (at-rest, during processing, or in transmission), software, administrative authorities, mobile devices, output, and offline system components is restricted through the use of access control software and rule sets.Identifies and Authenticates Users - Persons, infrastructure and software are identified and authenticated prior to accessing information assets, whether locally or remotely.Considers Network Segmentation - Network segmentation permits unrelated portions of the entity's information system to be isolated from each other.Manages Points of Access - Points of access by outside entities and the types of data that flow through the points of access are identified, inventoried, and managed. The types of individuals and systems using each point of access are identified, documented, and managed.Restricts Access to Information Assets - Combinations of data classification, separate data structures, port restrictions, access protocol restrictions, user identification, and digital certificates are used to establish access control rules for information assets.Manages Identification and Authentication - Identification and authentication requirements are established, documented, and managed for individuals and systems accessing entity information, infrastructure and software.Manages Credentials for Infrastructure and Software - New internal and external infrastructure and software are registered, authorized, and documented prior to being granted access credentials and implemented on the network or access point. Credentials are removed and access is disabled when access is no longer required or the infrastructure and software are no longer in use.Uses Encryption to Protect Data - The entity uses encryption to supplement other measures used to protect data-at-rest, when such protections are deemed appropriate based on assessed risk.Protects Encryption Keys - Processes are in place to protect encryption keys during generation, storage, use, and destruction.",
|
||||
"Description": "Identifies and Manages the Inventory of Information Assets - The entity identifies, inventories, classifies, and manages information assets. Restricts Logical Access - Logical access to information assets, including hardware, data (at-rest, during processing, or in transmission), software, administrative authorities, mobile devices, output, and offline system components is restricted through the use of access control software and rule sets. Identifies and Authenticates Users - Persons, infrastructure and software are identified and authenticated prior to accessing information assets, whether locally or remotely. Considers Network Segmentation - Network segmentation permits unrelated portions of the entity's information system to be isolated from each other. Manages Points of Access - Points of access by outside entities and the types of data that flow through the points of access are identified, inventoried, and managed. The types of individuals and systems using each point of access are identified, documented, and managed. Restricts Access to Information Assets - Combinations of data classification, separate data structures, port restrictions, access protocol restrictions, user identification, and digital certificates are used to establish access control rules for information assets. Manages Identification and Authentication - Identification and authentication requirements are established, documented, and managed for individuals and systems accessing entity information, infrastructure and software. Manages Credentials for Infrastructure and Software - New internal and external infrastructure and software are registered, authorized, and documented prior to being granted access credentials and implemented on the network or access point. Credentials are removed and access is disabled when access is no longer required or the infrastructure and software are no longer in use. Uses Encryption to Protect Data - The entity uses encryption to supplement other measures used to protect data-at-rest, when such protections are deemed appropriate based on assessed risk. Protects Encryption Keys - Processes are in place to protect encryption keys during generation, storage, use, and destruction.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_6_1",
|
||||
@@ -285,7 +287,7 @@
|
||||
{
|
||||
"Id": "cc_6_2",
|
||||
"Name": "CC6.2 Prior to issuing system credentials and granting system access, the entity registers and authorizes new internal and external users whose access is administered by the entity",
|
||||
"Description": "Prior to issuing system credentials and granting system access, the entity registers and authorizes new internal and external users whose access is administered by the entity. For those users whose access is administered by the entity, user system credentials are removed when user access is no longer authorized.Controls Access Credentials to Protected Assets - Information asset access credentials are created based on an authorization from the system's asset owner or authorized custodian.Removes Access to Protected Assets When Appropriate - Processes are in place to remove credential access when an individual no longer requires such access.Reviews Appropriateness of Access Credentials - The appropriateness of access credentials is reviewed on a periodic basis for unnecessary and inappropriate individuals with credentials.",
|
||||
"Description": "Prior to issuing system credentials and granting system access, the entity registers and authorizes new internal and external users whose access is administered by the entity. For those users whose access is administered by the entity, user system credentials are removed when user access is no longer authorized. Controls Access Credentials to Protected Assets - Information asset access credentials are created based on an authorization from the system's asset owner or authorized custodian. Removes Access to Protected Assets When Appropriate - Processes are in place to remove credential access when an individual no longer requires such access. Reviews Appropriateness of Access Credentials - The appropriateness of access credentials is reviewed on a periodic basis for unnecessary and inappropriate individuals with credentials.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_6_2",
|
||||
@@ -301,7 +303,7 @@
|
||||
{
|
||||
"Id": "cc_6_3",
|
||||
"Name": "CC6.3 The entity authorizes, modifies, or removes access to data, software, functions, and other protected information assets based on roles, responsibilities, or the system design and changes, giving consideration to the concepts of least privilege and segregation of duties, to meet the entity’s objectives",
|
||||
"Description": "Creates or Modifies Access to Protected Information Assets - Processes are in place to create or modify access to protected information assets based on authorization from the asset’s owner.Removes Access to Protected Information Assets - Processes are in place to remove access to protected information assets when an individual no longer requires access.Uses Role-Based Access Controls - Role-based access control is utilized to support segregation of incompatible functions.",
|
||||
"Description": "Creates or Modifies Access to Protected Information Assets - Processes are in place to create or modify access to protected information assets based on authorization from the asset’s owner. Removes Access to Protected Information Assets - Processes are in place to remove access to protected information assets when an individual no longer requires access. Uses Role-Based Access Controls - Role-based access control is utilized to support segregation of incompatible functions.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_6_3",
|
||||
@@ -311,13 +313,15 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"iam_policy_no_administrative_privileges"
|
||||
"iam_aws_attached_policy_no_administrative_privileges",
|
||||
"iam_customer_attached_policy_no_administrative_privileges",
|
||||
"iam_inline_policy_no_administrative_privileges"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": "cc_6_4",
|
||||
"Name": "CC6.4 The entity restricts physical access to facilities and protected information assets to authorized personnel to meet the entity’s objectives",
|
||||
"Description": "Creates or Modifies Physical Access - Processes are in place to create or modify physical access to facilities such as data centers, office spaces, and work areas, based on authorization from the system's asset owner.Removes Physical Access - Processes are in place to remove access to physical resources when an individual no longer requires access.Reviews Physical Access - Processes are in place to periodically review physical access to ensure consistency with job responsibilities.",
|
||||
"Description": "Creates or Modifies Physical Access - Processes are in place to create or modify physical access to facilities such as data centers, office spaces, and work areas, based on authorization from the system's asset owner. Removes Physical Access - Processes are in place to remove access to physical resources when an individual no longer requires access. Reviews Physical Access - Processes are in place to periodically review physical access to ensure consistency with job responsibilities.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_6_4",
|
||||
@@ -331,7 +335,7 @@
|
||||
{
|
||||
"Id": "cc_6_5",
|
||||
"Name": "CC6.5 The entity discontinues logical and physical protections over physical assets only after the ability to read or recover data and software from those assets has been diminished and is no longer required to meet the entity’s objectives",
|
||||
"Description": "Identifies Data and Software for Disposal - Procedures are in place to identify data and software stored on equipment to be disposed and to render such data and software unreadable.Removes Data and Software From Entity Control - Procedures are in place to remove data and software stored on equipment to be removed from the physical control of the entity and to render such data and software unreadable.",
|
||||
"Description": "Identifies Data and Software for Disposal - Procedures are in place to identify data and software stored on equipment to be disposed and to render such data and software unreadable. Removes Data and Software From Entity Control - Procedures are in place to remove data and software stored on equipment to be removed from the physical control of the entity and to render such data and software unreadable.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_6_5",
|
||||
@@ -345,7 +349,7 @@
|
||||
{
|
||||
"Id": "cc_6_6",
|
||||
"Name": "CC6.6 The entity implements logical access security measures to protect against threats from sources outside its system boundaries",
|
||||
"Description": "Restricts Access — The types of activities that can occur through a communication channel (for example, FTP site, router port) are restricted.Protects Identification and Authentication Credentials — Identification and authentication credentials are protected during transmission outside its system boundaries.Requires Additional Authentication or Credentials — Additional authentication information or credentials are required when accessing the system from outside its boundaries.Implements Boundary Protection Systems — Boundary protection systems (for example, firewalls, demilitarized zones, and intrusion detection systems) are implemented to protect external access points from attempts and unauthorized access and are monitored to detect such attempts.",
|
||||
"Description": "Restricts Access — The types of activities that can occur through a communication channel (for example, FTP site, router port) are restricted. Protects Identification and Authentication Credentials — Identification and authentication credentials are protected during transmission outside its system boundaries. Requires Additional Authentication or Credentials — Additional authentication information or credentials are required when accessing the system from outside its boundaries. Implements Boundary Protection Systems — Boundary protection systems (for example, firewalls, demilitarized zones, and intrusion detection systems) are implemented to protect external access points from attempts and unauthorized access and are monitored to detect such attempts.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_6_6",
|
||||
@@ -361,7 +365,7 @@
|
||||
{
|
||||
"Id": "cc_6_7",
|
||||
"Name": "CC6.7 The entity restricts the transmission, movement, and removal of information to authorized internal and external users and processes, and protects it during transmission, movement, or removal to meet the entity’s objectives",
|
||||
"Description": "Restricts the Ability to Perform Transmission - Data loss prevention processes and technologies are used to restrict ability to authorize and execute transmission, movement and removal of information.Uses Encryption Technologies or Secure Communication Channels to Protect Data - Encryption technologies or secured communication channels are used to protect transmission of data and other communications beyond connectivity access points.Protects Removal Media - Encryption technologies and physical asset protections are used for removable media (such as USB drives and back-up tapes), as appropriate.Protects Mobile Devices - Processes are in place to protect mobile devices (such as laptops, smart phones and tablets) that serve as information assets.",
|
||||
"Description": "Restricts the Ability to Perform Transmission - Data loss prevention processes and technologies are used to restrict ability to authorize and execute transmission, movement and removal of information. Uses Encryption Technologies or Secure Communication Channels to Protect Data - Encryption technologies or secured communication channels are used to protect transmission of data and other communications beyond connectivity access points. Protects Removal Media - Encryption technologies and physical asset protections are used for removable media (such as USB drives and back-up tapes), as appropriate. Protects Mobile Devices - Processes are in place to protect mobile devices (such as laptops, smart phones and tablets) that serve as information assets.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_6_7",
|
||||
@@ -377,7 +381,7 @@
|
||||
{
|
||||
"Id": "cc_6_8",
|
||||
"Name": "CC6.8 The entity implements controls to prevent or detect and act upon the introduction of unauthorized or malicious software to meet the entity’s objectives",
|
||||
"Description": "Restricts Application and Software Installation - The ability to install applications and software is restricted to authorized individuals.Detects Unauthorized Changes to Software and Configuration Parameters - Processes are in place to detect changes to software and configuration parameters that may be indicative of unauthorized or malicious software.Uses a Defined Change Control Process - A management-defined change control process is used for the implementation of software.Uses Antivirus and Anti-Malware Software - Antivirus and anti-malware software is implemented and maintained to provide for the interception or detection and remediation of malware.Scans Information Assets from Outside the Entity for Malware and Other Unauthorized Software - Procedures are in place to scan information assets that have been transferred or returned to the entity’s custody for malware and other unauthorized software and to remove any items detected prior to its implementation on the network.",
|
||||
"Description": "Restricts Application and Software Installation - The ability to install applications and software is restricted to authorized individuals. Detects Unauthorized Changes to Software and Configuration Parameters - Processes are in place to detect changes to software and configuration parameters that may be indicative of unauthorized or malicious software. Uses a Defined Change Control Process - A management-defined change control process is used for the implementation of software. Uses Antivirus and Anti-Malware Software - Antivirus and anti-malware software is implemented and maintained to provide for the interception or detection and remediation of malware. Scans Information Assets from Outside the Entity for Malware and Other Unauthorized Software - Procedures are in place to scan information assets that have been transferred or returned to the entity’s custody for malware and other unauthorized software and to remove any items detected prior to its implementation on the network.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_6_8",
|
||||
@@ -394,7 +398,7 @@
|
||||
{
|
||||
"Id": "cc_7_1",
|
||||
"Name": "CC7.1 To meet its objectives, the entity uses detection and monitoring procedures to identify (1) changes to configurations that result in the introduction of new vulnerabilities, and (2) susceptibilities to newly discovered vulnerabilities",
|
||||
"Description": "Uses Defined Configuration Standards - Management has defined configuration standards.Monitors Infrastructure and Software - The entity monitors infrastructure and software for noncompliance with the standards, which could threaten the achievement of the entity's objectives.Implements Change-Detection Mechanisms - The IT system includes a change-detection mechanism (for example, file integrity monitoring tools) to alert personnel to unauthorized modifications of critical system files, configuration files, or content files.Detects Unknown or Unauthorized Components - Procedures are in place to detect the introduction of unknown or unauthorized components.Conducts Vulnerability Scans - The entity conducts vulnerability scans designed to identify potential vulnerabilities or misconfigurations on a periodic basis and after any significant change in the environment and takes action to remediate identified deficiencies on a timely basis.",
|
||||
"Description": "Uses Defined Configuration Standards - Management has defined configuration standards. Monitors Infrastructure and Software - The entity monitors infrastructure and software for noncompliance with the standards, which could threaten the achievement of the entity's objectives. Implements Change-Detection Mechanisms - The IT system includes a change-detection mechanism (for example, file integrity monitoring tools) to alert personnel to unauthorized modifications of critical system files, configuration files, or content files. Detects Unknown or Unauthorized Components - Procedures are in place to detect the introduction of unknown or unauthorized components. Conducts Vulnerability Scans - The entity conducts vulnerability scans designed to identify potential vulnerabilities or misconfigurations on a periodic basis and after any significant change in the environment and takes action to remediate identified deficiencies on a timely basis.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_7_1",
|
||||
@@ -413,7 +417,7 @@
|
||||
{
|
||||
"Id": "cc_7_2",
|
||||
"Name": "CC7.2 The entity monitors system components and the operation of those components for anomalies that are indicative of malicious acts, natural disasters, and errors affecting the entity's ability to meet its objectives; anomalies are analyzed to determine whether they represent security events",
|
||||
"Description": "Implements Detection Policies, Procedures, and Tools - Detection policies and procedures are defined and implemented, and detection tools are implemented on Infrastructure and software to identify anomalies in the operation or unusual activity on systems. Procedures may include (1) a defined governance process for security event detection and management that includes provision of resources; (2) use of intelligence sources to identify newly discovered threats and vulnerabilities; and (3) logging of unusual system activities.Designs Detection Measures - Detection measures are designed to identify anomalies that could result from actual or attempted (1) compromise of physical barriers; (2) unauthorized actions of authorized personnel; (3) use of compromised identification and authentication credentials; (4) unauthorized access from outside the system boundaries; (5) compromise of authorized external parties; and (6) implementation or connection of unauthorized hardware and software.Implements Filters to Analyze Anomalies - Management has implemented procedures to filter, summarize, and analyze anomalies to identify security events.Monitors Detection Tools for Effective Operation - Management has implemented processes to monitor the effectiveness of detection tools.",
|
||||
"Description": "Implements Detection Policies, Procedures, and Tools - Detection policies and procedures are defined and implemented, and detection tools are implemented on Infrastructure and software to identify anomalies in the operation or unusual activity on systems. Procedures may include (1) a defined governance process for security event detection and management that includes provision of resources; (2) use of intelligence sources to identify newly discovered threats and vulnerabilities; and (3) logging of unusual system activities. Designs Detection Measures - Detection measures are designed to identify anomalies that could result from actual or attempted (1) compromise of physical barriers; (2) unauthorized actions of authorized personnel; (3) use of compromised identification and authentication credentials; (4) unauthorized access from outside the system boundaries; (5) compromise of authorized external parties; and (6) implementation or connection of unauthorized hardware and software. Implements Filters to Analyze Anomalies - Management has implemented procedures to filter, summarize, and analyze anomalies to identify security events. Monitors Detection Tools for Effective Operation - Management has implemented processes to monitor the effectiveness of detection tools.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_7_2",
|
||||
@@ -449,7 +453,7 @@
|
||||
{
|
||||
"Id": "cc_7_3",
|
||||
"Name": "CC7.3 The entity evaluates security events to determine whether they could or have resulted in a failure of the entity to meet its objectives (security incidents) and, if so, takes actions to prevent or address such failures",
|
||||
"Description": "Responds to Security Incidents - Procedures are in place for responding to security incidents and evaluating the effectiveness of those policies and procedures on a periodic basis.Communicates and Reviews Detected Security Events - Detected security events are communicated to and reviewed by the individuals responsible for the management of the security program and actions are taken, if necessary.Develops and Implements Procedures to Analyze Security Incidents - Procedures are in place to analyze security incidents and determine system impact.Assesses the Impact on Personal Information - Detected security events are evaluated to determine whether they could or did result in the unauthorized disclosure or use of personal information and whether there has been a failure to comply with applicable laws or regulations.Determines Personal Information Used or Disclosed - When an unauthorized use or disclosure of personal information has occurred, the affected information is identified.",
|
||||
"Description": "Responds to Security Incidents - Procedures are in place for responding to security incidents and evaluating the effectiveness of those policies and procedures on a periodic basis. Communicates and Reviews Detected Security Events - Detected security events are communicated to and reviewed by the individuals responsible for the management of the security program and actions are taken, if necessary. Develops and Implements Procedures to Analyze Security Incidents - Procedures are in place to analyze security incidents and determine system impact. Assesses the Impact on Personal Information - Detected security events are evaluated to determine whether they could or did result in the unauthorized disclosure or use of personal information and whether there has been a failure to comply with applicable laws or regulations. Determines Personal Information Used or Disclosed - When an unauthorized use or disclosure of personal information has occurred, the affected information is identified.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_7_3",
|
||||
@@ -481,7 +485,7 @@
|
||||
{
|
||||
"Id": "cc_7_4",
|
||||
"Name": "CC7.4 The entity responds to identified security incidents by executing a defined incident response program to understand, contain, remediate, and communicate security incidents, as appropriate",
|
||||
"Description": "Assigns Roles and Responsibilities - Roles and responsibilities for the design, implementation, maintenance, and execution of the incident response program are assigned, including the use of external resources when necessary.Contains Security Incidents - Procedures are in place to contain security incidents that actively threaten entity objectives.Mitigates Ongoing Security Incidents - Procedures are in place to mitigate the effects of ongoing security incidents.Ends Threats Posed by Security Incidents - Procedures are in place to end the threats posed by security incidents through closure of the vulnerability, removal of unauthorized access, and other remediation actions.Restores Operations - Procedures are in place to restore data and business operations to an interim state that permits the achievement of entity objectives. Develops and Implements Communication Protocols for Security Incidents - Protocols for communicating security incidents and actions taken to affected parties are developed and implemented to meet the entity's objectives.Obtains Understanding of Nature of Incident and Determines Containment Strategy - An understanding of the nature (for example, the method by which the incident occurred and the affected system resources) and severity of the security incident is obtained to determine the appropriate containment strategy, including (1) a determination of the appropriate response time frame, and (2) the determination and execution of the containment approach.Remediates Identified Vulnerabilities - Identified vulnerabilities are remediated through the development and execution of remediation activities.Communicates Remediation Activities - Remediation activities are documented and communicated in accordance with the incident response program.Evaluates the Effectiveness of Incident Response - The design of incident response activities is evaluated for effectiveness on a periodic basis.Periodically Evaluates Incidents - Periodically, management reviews incidents related to security, availability, processing integrity, confidentiality, and privacy and identifies the need for system changes based on incident patterns and root causes. Communicates Unauthorized Use and Disclosure - Events that resulted in unauthorized use or disclosure of personal information are communicated to the data subjects, legal and regulatory authorities, and others as required.Application of Sanctions - The conduct of individuals and organizations operating under the authority of the entity and involved in the unauthorized use or disclosure of personal information is evaluated and, if appropriate, sanctioned in accordance with entity policies and legal and regulatory requirements.",
|
||||
"Description": "Assigns Roles and Responsibilities - Roles and responsibilities for the design, implementation, maintenance, and execution of the incident response program are assigned, including the use of external resources when necessary. Contains Security Incidents - Procedures are in place to contain security incidents that actively threaten entity objectives. Mitigates Ongoing Security Incidents - Procedures are in place to mitigate the effects of ongoing security incidents. Ends Threats Posed by Security Incidents - Procedures are in place to end the threats posed by security incidents through closure of the vulnerability, removal of unauthorized access, and other remediation actions. Restores Operations - Procedures are in place to restore data and business operations to an interim state that permits the achievement of entity objectives. Develops and Implements Communication Protocols for Security Incidents - Protocols for communicating security incidents and actions taken to affected parties are developed and implemented to meet the entity's objectives. Obtains Understanding of Nature of Incident and Determines Containment Strategy - An understanding of the nature (for example, the method by which the incident occurred and the affected system resources) and severity of the security incident is obtained to determine the appropriate containment strategy, including (1) a determination of the appropriate response time frame, and (2) the determination and execution of the containment approach. Remediates Identified Vulnerabilities - Identified vulnerabilities are remediated through the development and execution of remediation activities. Communicates Remediation Activities - Remediation activities are documented and communicated in accordance with the incident response program. Evaluates the Effectiveness of Incident Response - The design of incident response activities is evaluated for effectiveness on a periodic basis. Periodically Evaluates Incidents - Periodically, management reviews incidents related to security, availability, processing integrity, confidentiality, and privacy and identifies the need for system changes based on incident patterns and root causes. Communicates Unauthorized Use and Disclosure - Events that resulted in unauthorized use or disclosure of personal information are communicated to the data subjects, legal and regulatory authorities, and others as required. Application of Sanctions - The conduct of individuals and organizations operating under the authority of the entity and involved in the unauthorized use or disclosure of personal information is evaluated and, if appropriate, sanctioned in accordance with entity policies and legal and regulatory requirements.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_7_4",
|
||||
@@ -512,7 +516,7 @@
|
||||
{
|
||||
"Id": "cc_7_5",
|
||||
"Name": "CC7.5 The entity identifies, develops, and implements activities to recover from identified security incidents",
|
||||
"Description": "Restores the Affected Environment - The activities restore the affected environment to functional operation by rebuilding systems, updating software, installing patches, and changing configurations, as needed.Communicates Information About the Event - Communications about the nature of the incident, recovery actions taken, and activities required for the prevention of future security events are made to management and others as appropriate (internal and external).Determines Root Cause of the Event - The root cause of the event is determined.Implements Changes to Prevent and Detect Recurrences - Additional architecture or changes to preventive and detective controls, or both, are implemented to prevent and detect recurrences on a timely basis.Improves Response and Recovery Procedures - Lessons learned are analyzed, and the incident response plan and recovery procedures are improved.Implements Incident Recovery Plan Testing - Incident recovery plan testing is performed on a periodic basis. The testing includes (1) development of testing scenarios based on threat likelihood and magnitude; (2) consideration of relevant system components from across the entity that can impair availability; (3) scenarios that consider the potential for the lack of availability of key personnel; and (4) revision of continuity plans and systems based on test results.",
|
||||
"Description": "Restores the Affected Environment - The activities restore the affected environment to functional operation by rebuilding systems, updating software, installing patches, and changing configurations, as needed. Communicates Information About the Event - Communications about the nature of the incident, recovery actions taken, and activities required for the prevention of future security events are made to management and others as appropriate (internal and external). Determines Root Cause of the Event - The root cause of the event is determined. Implements Changes to Prevent and Detect Recurrences - Additional architecture or changes to preventive and detective controls, or both, are implemented to prevent and detect recurrences on a timely basis. Improves Response and Recovery Procedures - Lessons learned are analyzed, and the incident response plan and recovery procedures are improved. Implements Incident Recovery Plan Testing - Incident recovery plan testing is performed on a periodic basis. The testing includes (1) development of testing scenarios based on threat likelihood and magnitude; (2) consideration of relevant system components from across the entity that can impair availability; (3) scenarios that consider the potential for the lack of availability of key personnel; and (4) revision of continuity plans and systems based on test results.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_7_5",
|
||||
@@ -526,7 +530,7 @@
|
||||
{
|
||||
"Id": "cc_8_1",
|
||||
"Name": "CC8.1 The entity authorizes, designs, develops or acquires, configures, documents, tests, approves, and implements changes to infrastructure, data, software, and procedures to meet its objectives",
|
||||
"Description": "Manages Changes Throughout the System Lifecycle - A process for managing system changes throughout the lifecycle of the system and its components (infrastructure, data, software and procedures) is used to support system availability and processing integrity.Authorizes Changes - A process is in place to authorize system changes prior to development.Designs and Develops Changes - A process is in place to design and develop system changes.Documents Changes - A process is in place to document system changes to support ongoing maintenance of the system and to support system users in performing their responsibilities.Tracks System Changes - A process is in place to track system changes prior to implementation.Configures Software - A process is in place to select and implement the configuration parameters used to control the functionality of software.Tests System Changes - A process is in place to test system changes prior to implementation.Approves System Changes - A process is in place to approve system changes prior to implementation.Deploys System Changes - A process is in place to implement system changes.Identifies and Evaluates System Changes - Objectives affected by system changes are identified, and the ability of the modified system to meet the objectives is evaluated throughout the system development life cycle.Identifies Changes in Infrastructure, Data, Software, and Procedures Required to Remediate Incidents - Changes in infrastructure, data, software, and procedures required to remediate incidents to continue to meet objectives are identified, and the change process is initiated upon identification.Creates Baseline Configuration of IT Technology - A baseline configuration of IT and control systems is created and maintained.Provides for Changes Necessary in Emergency Situations - A process is in place for authorizing, designing, testing, approving and implementing changes necessary in emergency situations (that is, changes that need to be implemented in an urgent timeframe).Protects Confidential Information - The entity protects confidential information during system design, development, testing, implementation, and change processes to meet the entity’s objectives related to confidentiality.Protects Personal Information - The entity protects personal information during system design, development, testing, implementation, and change processes to meet the entity’s objectives related to privacy.",
|
||||
"Description": "Manages Changes Throughout the System Lifecycle - A process for managing system changes throughout the lifecycle of the system and its components (infrastructure, data, software and procedures) is used to support system availability and processing integrity. Authorizes Changes - A process is in place to authorize system changes prior to development. Designs and Develops Changes - A process is in place to design and develop system changes. Documents Changes - A process is in place to document system changes to support ongoing maintenance of the system and to support system users in performing their responsibilities. Tracks System Changes - A process is in place to track system changes prior to implementation. Configures Software - A process is in place to select and implement the configuration parameters used to control the functionality of software. Tests System Changes - A process is in place to test system changes prior to implementation. Approves System Changes - A process is in place to approve system changes prior to implementation. Deploys System Changes - A process is in place to implement system changes. Identifies and Evaluates System Changes - Objectives affected by system changes are identified, and the ability of the modified system to meet the objectives is evaluated throughout the system development life cycle. Identifies Changes in Infrastructure, Data, Software, and Procedures Required to Remediate Incidents - Changes in infrastructure, data, software, and procedures required to remediate incidents to continue to meet objectives are identified, and the change process is initiated upon identification. Creates Baseline Configuration of IT Technology - A baseline configuration of IT and control systems is created and maintained. Provides for Changes Necessary in Emergency Situations - A process is in place for authorizing, designing, testing, approving and implementing changes necessary in emergency situations (that is, changes that need to be implemented in an urgent timeframe). Protects Confidential Information - The entity protects confidential information during system design, development, testing, implementation, and change processes to meet the entity’s objectives related to confidentiality. Protects Personal Information - The entity protects personal information during system design, development, testing, implementation, and change processes to meet the entity’s objectives related to privacy.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_8_1",
|
||||
@@ -542,7 +546,7 @@
|
||||
{
|
||||
"Id": "cc_9_1",
|
||||
"Name": "CC9.1 The entity identifies, selects, and develops risk mitigation activities for risks arising from potential business disruptions",
|
||||
"Description": "Considers Mitigation of Risks of Business Disruption - Risk mitigation activities include the development of planned policies, procedures, communications, and alternative processing solutions to respond to, mitigate, and recover from security events that disrupt business operations. Those policies and procedures include monitoring processes and information and communications to meet the entity's objectives during response, mitigation, and recovery efforts.Considers the Use of Insurance to Mitigate Financial Impact Risks - The risk management activities consider the use of insurance to offset the financial impact of loss events that would otherwise impair the ability of the entity to meet its objectives.",
|
||||
"Description": "Considers Mitigation of Risks of Business Disruption - Risk mitigation activities include the development of planned policies, procedures, communications, and alternative processing solutions to respond to, mitigate, and recover from security events that disrupt business operations. Those policies and procedures include monitoring processes and information and communications to meet the entity's objectives during response, mitigation, and recovery efforts. Considers the Use of Insurance to Mitigate Financial Impact Risks - The risk management activities consider the use of insurance to offset the financial impact of loss events that would otherwise impair the ability of the entity to meet its objectives.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_9_1",
|
||||
@@ -556,7 +560,7 @@
|
||||
{
|
||||
"Id": "cc_9_2",
|
||||
"Name": "CC9.2 The entity assesses and manages risks associated with vendors and business partners",
|
||||
"Description": "Establishes Requirements for Vendor and Business Partner Engagements - The entity establishes specific requirements for a vendor and business partner engagement that includes (1) scope of services and product specifications, (2) roles and responsibilities, (3) compliance requirements, and (4) service levels.Assesses Vendor and Business Partner Risks - The entity assesses, on a periodic basis, the risks that vendors and business partners (and those entities’ vendors and business partners) represent to the achievement of the entity's objectives.Assigns Responsibility and Accountability for Managing Vendors and Business Partners - The entity assigns responsibility and accountability for the management of risks associated with vendors and business partners.Establishes Communication Protocols for Vendors and Business Partners - The entity establishes communication and resolution protocols for service or product issues related to vendors and business partners.Establishes Exception Handling Procedures From Vendors and Business Partners - The entity establishes exception handling procedures for service or product issues related to vendors and business partners.Assesses Vendor and Business Partner Performance - The entity periodically assesses the performance of vendors and business partners.Implements Procedures for Addressing Issues Identified During Vendor and Business Partner Assessments - The entity implements procedures for addressing issues identified with vendor and business partner relationships.Implements Procedures for Terminating Vendor and Business Partner Relationships - The entity implements procedures for terminating vendor and business partner relationships.Obtains Confidentiality Commitments from Vendors and Business Partners - The entity obtains confidentiality commitments that are consistent with the entity’s confidentiality commitments and requirements from vendors and business partners who have access to confidential information.Assesses Compliance With Confidentiality Commitments of Vendors and Business Partners - On a periodic and as-needed basis, the entity assesses compliance by vendors and business partners with the entity’s confidentiality commitments and requirements.Obtains Privacy Commitments from Vendors and Business Partners - The entity obtains privacy commitments, consistent with the entity’s privacy commitments and requirements, from vendors and business partners who have access to personal information.Assesses Compliance with Privacy Commitments of Vendors and Business Partners - On a periodic and as-needed basis, the entity assesses compliance by vendors and business partners with the entity’s privacy commitments and requirements and takes corrective action as necessary.",
|
||||
"Description": "Establishes Requirements for Vendor and Business Partner Engagements - The entity establishes specific requirements for a vendor and business partner engagement that includes (1) scope of services and product specifications, (2) roles and responsibilities, (3) compliance requirements, and (4) service levels. Assesses Vendor and Business Partner Risks - The entity assesses, on a periodic basis, the risks that vendors and business partners (and those entities’ vendors and business partners) represent to the achievement of the entity's objectives. Assigns Responsibility and Accountability for Managing Vendors and Business Partners - The entity assigns responsibility and accountability for the management of risks associated with vendors and business partners. Establishes Communication Protocols for Vendors and Business Partners - The entity establishes communication and resolution protocols for service or product issues related to vendors and business partners. Establishes Exception Handling Procedures From Vendors and Business Partners - The entity establishes exception handling procedures for service or product issues related to vendors and business partners. Assesses Vendor and Business Partner Performance - The entity periodically assesses the performance of vendors and business partners. Implements Procedures for Addressing Issues Identified During Vendor and Business Partner Assessments - The entity implements procedures for addressing issues identified with vendor and business partner relationships. Implements Procedures for Terminating Vendor and Business Partner Relationships - The entity implements procedures for terminating vendor and business partner relationships. Obtains Confidentiality Commitments from Vendors and Business Partners - The entity obtains confidentiality commitments that are consistent with the entity’s confidentiality commitments and requirements from vendors and business partners who have access to confidential information. Assesses Compliance With Confidentiality Commitments of Vendors and Business Partners - On a periodic and as-needed basis, the entity assesses compliance by vendors and business partners with the entity’s confidentiality commitments and requirements. Obtains Privacy Commitments from Vendors and Business Partners - The entity obtains privacy commitments, consistent with the entity’s privacy commitments and requirements, from vendors and business partners who have access to personal information. Assesses Compliance with Privacy Commitments of Vendors and Business Partners - On a periodic and as-needed basis, the entity assesses compliance by vendors and business partners with the entity’s privacy commitments and requirements and takes corrective action as necessary.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_9_2",
|
||||
@@ -570,7 +574,7 @@
|
||||
{
|
||||
"Id": "cc_a_1_1",
|
||||
"Name": "A1.1 The entity maintains, monitors, and evaluates current processing capacity and use of system components (infrastructure, data, and software) to manage capacity demand and to enable the implementation of additional capacity to help meet its objectives",
|
||||
"Description": "Measures Current Usage - The use of the system components is measured to establish a baseline for capacity management and to use when evaluating the risk of impaired availability due to capacity constraints.Forecasts Capacity - The expected average and peak use of system components is forecasted and compared to system capacity and associated tolerances. Forecasting considers capacity in the event of the failure of system components that constrain capacity.Makes Changes Based on Forecasts - The system change management process is initiated when forecasted usage exceeds capacity tolerances.",
|
||||
"Description": "Measures Current Usage - The use of the system components is measured to establish a baseline for capacity management and to use when evaluating the risk of impaired availability due to capacity constraints. Forecasts Capacity - The expected average and peak use of system components is forecasted and compared to system capacity and associated tolerances. Forecasting considers capacity in the event of the failure of system components that constrain capacity. Makes Changes Based on Forecasts - The system change management process is initiated when forecasted usage exceeds capacity tolerances.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_a_1_1",
|
||||
@@ -584,7 +588,7 @@
|
||||
{
|
||||
"Id": "cc_a_1_2",
|
||||
"Name": "A1.2 The entity authorizes, designs, develops or acquires, implements, operates, approves, maintains, and monitors environmental protections, software, data back-up processes, and recovery infrastructure to meet its objectives",
|
||||
"Description": "Measures Current Usage - The use of the system components is measured to establish a baseline for capacity management and to use when evaluating the risk of impaired availability due to capacity constraints.Forecasts Capacity - The expected average and peak use of system components is forecasted and compared to system capacity and associated tolerances. Forecasting considers capacity in the event of the failure of system components that constrain capacity.Makes Changes Based on Forecasts - The system change management process is initiated when forecasted usage exceeds capacity tolerances.",
|
||||
"Description": "Measures Current Usage - The use of the system components is measured to establish a baseline for capacity management and to use when evaluating the risk of impaired availability due to capacity constraints. Forecasts Capacity - The expected average and peak use of system components is forecasted and compared to system capacity and associated tolerances. Forecasting considers capacity in the event of the failure of system components that constrain capacity. Makes Changes Based on Forecasts - The system change management process is initiated when forecasted usage exceeds capacity tolerances.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_a_1_2",
|
||||
@@ -615,7 +619,7 @@
|
||||
{
|
||||
"Id": "cc_a_1_3",
|
||||
"Name": "A1.3 The entity tests recovery plan procedures supporting system recovery to meet its objectives",
|
||||
"Description": "Implements Business Continuity Plan Testing - Business continuity plan testing is performed on a periodic basis. The testing includes (1) development of testing scenarios based on threat likelihood and magnitude; (2) consideration of system components from across the entity that can impair the availability; (3) scenarios that consider the potential for the lack of availability of key personnel; and (4) revision of continuity plans and systems based on test results.Tests Integrity and Completeness of Back-Up Data - The integrity and completeness of back-up information is tested on a periodic basis.",
|
||||
"Description": "Implements Business Continuity Plan Testing - Business continuity plan testing is performed on a periodic basis. The testing includes (1) development of testing scenarios based on threat likelihood and magnitude; (2) consideration of system components from across the entity that can impair the availability; (3) scenarios that consider the potential for the lack of availability of key personnel; and (4) revision of continuity plans and systems based on test results. Tests Integrity and Completeness of Back-Up Data - The integrity and completeness of back-up information is tested on a periodic basis.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_a_1_3",
|
||||
@@ -629,7 +633,7 @@
|
||||
{
|
||||
"Id": "cc_c_1_1",
|
||||
"Name": "C1.1 The entity identifies and maintains confidential information to meet the entity’s objectives related to confidentiality",
|
||||
"Description": "Identifies Confidential information - Procedures are in place to identify and designate confidential information when it is received or created and to determine the period over which the confidential information is to be retained.Protects Confidential Information from Destruction - Procedures are in place to protect confidential information from erasure or destruction during the specified retention period of the information",
|
||||
"Description": "Identifies Confidential information - Procedures are in place to identify and designate confidential information when it is received or created and to determine the period over which the confidential information is to be retained. Protects Confidential Information from Destruction - Procedures are in place to protect confidential information from erasure or destruction during the specified retention period of the information",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_c_1_1",
|
||||
@@ -645,7 +649,7 @@
|
||||
{
|
||||
"Id": "cc_c_1_2",
|
||||
"Name": "C1.2 The entity disposes of confidential information to meet the entity’s objectives related to confidentiality",
|
||||
"Description": "Identifies Confidential Information for Destruction - Procedures are in place to identify confidential information requiring destruction when the end of the retention period is reached.Destroys Confidential Information - Procedures are in place to erase or otherwise destroy confidential information that has been identified for destruction.",
|
||||
"Description": "Identifies Confidential Information for Destruction - Procedures are in place to identify confidential information requiring destruction when the end of the retention period is reached. Destroys Confidential Information - Procedures are in place to erase or otherwise destroy confidential information that has been identified for destruction.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "cc_c_1_2",
|
||||
@@ -661,7 +665,7 @@
|
||||
{
|
||||
"Id": "p_1_1",
|
||||
"Name": "P1.1 The entity provides notice to data subjects about its privacy practices to meet the entity’s objectives related to privacy",
|
||||
"Description": "The entity provides notice to data subjects about its privacy practices to meet the entity’s objectives related to privacy. The notice is updated and communicated to data subjects in a timely manner for changes to the entity’s privacy practices, including changes in the use of personal information, to meet the entity’s objectives related to privacy.Communicates to Data Subjects - Notice is provided to data subjects regarding the following:Purpose for collecting personal informationChoice and consentTypes of personal information collectedMethods of collection (for example, use of cookies or other tracking techniques)Use, retention, and disposalAccessDisclosure to third partiesSecurity for privacyQuality, including data subjects’ responsibilities for qualityMonitoring and enforcementIf personal information is collected from sources other than the individual, such sources are described in the privacy notice.Provides Notice to Data Subjects - Notice is provided to data subjects (1) at or before the time personal information is collected or as soon as practical thereafter, (2) at or before the entity changes its privacy notice or as soon as practical thereafter, or (3) before personal information is used for new purposes not previously identified.Covers Entities and Activities in Notice - An objective description of the entities and activities covered is included in the entity’s privacy notice.Uses Clear and Conspicuous Language - The entity’s privacy notice is conspicuous and uses clear language.",
|
||||
"Description": "The entity provides notice to data subjects about its privacy practices to meet the entity’s objectives related to privacy. The notice is updated and communicated to data subjects in a timely manner for changes to the entity’s privacy practices, including changes in the use of personal information, to meet the entity’s objectives related to privacy. Communicates to Data Subjects - Notice is provided to data subjects regarding the following: Purpose for collecting personal informationChoice and consentTypes of personal information collectedMethods of collection (for example, use of cookies or other tracking techniques)Use, retention, and disposalAccessDisclosure to third partiesSecurity for privacyQuality, including data subjects’ responsibilities for qualityMonitoring and enforcementIf personal information is collected from sources other than the individual, such sources are described in the privacy notice. Provides Notice to Data Subjects - Notice is provided to data subjects (1) at or before the time personal information is collected or as soon as practical thereafter, (2) at or before the entity changes its privacy notice or as soon as practical thereafter, or (3) before personal information is used for new purposes not previously identified. Covers Entities and Activities in Notice - An objective description of the entities and activities covered is included in the entity’s privacy notice. Uses Clear and Conspicuous Language - The entity’s privacy notice is conspicuous and uses clear language.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "p_1_1",
|
||||
@@ -675,7 +679,7 @@
|
||||
{
|
||||
"Id": "p_2_1",
|
||||
"Name": "P2.1 The entity communicates choices available regarding the collection, use, retention, disclosure, and disposal of personal information to the data subjects and the consequences, if any, of each choice",
|
||||
"Description": "The entity communicates choices available regarding the collection, use, retention, disclosure, and disposal of personal information to the data subjects and the consequences, if any, of each choice. Explicit consent for the collection, use, retention, disclosure, and disposal of personal information is obtained from data subjects or other authorized persons, if required. Such consent is obtained only for the intended purpose of the information to meet the entity’s objectives related to privacy. The entity’s basis for determining implicit consent for the collection, use, retention, disclosure, and disposal of personal information is documented.Communicates to Data Subjects - Data subjects are informed (a) about the choices available to them with respect to the collection, use, and disclosure of personal information and (b) that implicit or explicit consent is required to collect, use, and disclose personal information, unless a law or regulation specifically requires or allows otherwise.Communicates Consequences of Denying or Withdrawing Consent - When personal information is collected, data subjects are informed of the consequences of refusing to provide personal information or denying or withdrawing consent to use personal information for purposes identified in the notice.Obtains Implicit or Explicit Consent - Implicit or explicit consent is obtained from data subjects at or before the time personal information is collected or soon thereafter. The individual’s preferences expressed in his or her consent are confirmed and implemented.Documents and Obtains Consent for New Purposes and Uses - If information that was previously collected is to be used for purposes not previously identified in the privacy notice, the new purpose is documented, the data subject is notified, and implicit or explicit consent is obtained prior to such new use or purpose.Obtains Explicit Consent for Sensitive Information - Explicit consent is obtained directly from the data subject when sensitive personal information is collected, used, or disclosed, unless a law or regulation specifically requires otherwise.",
|
||||
"Description": "The entity communicates choices available regarding the collection, use, retention, disclosure, and disposal of personal information to the data subjects and the consequences, if any, of each choice. Explicit consent for the collection, use, retention, disclosure, and disposal of personal information is obtained from data subjects or other authorized persons, if required. Such consent is obtained only for the intended purpose of the information to meet the entity’s objectives related to privacy. The entity’s basis for determining implicit consent for the collection, use, retention, disclosure, and disposal of personal information is documented. Communicates to Data Subjects - Data subjects are informed (a) about the choices available to them with respect to the collection, use, and disclosure of personal information and (b) that implicit or explicit consent is required to collect, use, and disclose personal information, unless a law or regulation specifically requires or allows otherwise. Communicates Consequences of Denying or Withdrawing Consent - When personal information is collected, data subjects are informed of the consequences of refusing to provide personal information or denying or withdrawing consent to use personal information for purposes identified in the notice. Obtains Implicit or Explicit Consent - Implicit or explicit consent is obtained from data subjects at or before the time personal information is collected or soon thereafter. The individual’s preferences expressed in his or her consent are confirmed and implemented. Documents and Obtains Consent for New Purposes and Uses - If information that was previously collected is to be used for purposes not previously identified in the privacy notice, the new purpose is documented, the data subject is notified, and implicit or explicit consent is obtained prior to such new use or purpose. Obtains Explicit Consent for Sensitive Information - Explicit consent is obtained directly from the data subject when sensitive personal information is collected, used, or disclosed, unless a law or regulation specifically requires otherwise.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "p_2_1",
|
||||
@@ -689,7 +693,7 @@
|
||||
{
|
||||
"Id": "p_3_1",
|
||||
"Name": "P3.1 Personal information is collected consistent with the entity’s objectives related to privacy",
|
||||
"Description": "Limits the Collection of Personal Information - The collection of personal information is limited to that necessary to meet the entity’s objectives.Collects Information by Fair and Lawful Means - Methods of collecting personal information are reviewed by management before they are implemented to confirm that personal information is obtained (a) fairly, without intimidation or deception, and (b) lawfully, adhering to all relevant rules of law, whether derived from statute or common law, relating to the collection of personal information.Collects Information From Reliable Sources - Management confirms that third parties from whom personal information is collected (that is, sources other than the individual) are reliable sources that collect information fairly and lawfully.Informs Data Subjects When Additional Information Is Acquired - Data subjects are informed if the entity develops or acquires additional information about them for its use.",
|
||||
"Description": "Limits the Collection of Personal Information - The collection of personal information is limited to that necessary to meet the entity’s objectives. Collects Information by Fair and Lawful Means - Methods of collecting personal information are reviewed by management before they are implemented to confirm that personal information is obtained (a) fairly, without intimidation or deception, and (b) lawfully, adhering to all relevant rules of law, whether derived from statute or common law, relating to the collection of personal information. Collects Information From Reliable Sources - Management confirms that third parties from whom personal information is collected (that is, sources other than the individual) are reliable sources that collect information fairly and lawfully. Informs Data Subjects When Additional Information Is Acquired - Data subjects are informed if the entity develops or acquires additional information about them for its use.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "p_3_1",
|
||||
@@ -703,7 +707,7 @@
|
||||
{
|
||||
"Id": "p_3_2",
|
||||
"Name": "P3.2 For information requiring explicit consent, the entity communicates the need for such consent, as well as the consequences of a failure to provide consent for the request for personal information, and obtains the consent prior to the collection of the information to meet the entity’s objectives related to privacy",
|
||||
"Description": "Obtains Explicit Consent for Sensitive Information - Explicit consent is obtained directly from the data subject when sensitive personal information is collected, used, or disclosed, unless a law or regulation specifically requires otherwise.Documents Explicit Consent to Retain Information - Documentation of explicit consent for the collection, use, or disclosure of sensitive personal information is retained in accordance with objectives related to privacy.",
|
||||
"Description": "Obtains Explicit Consent for Sensitive Information - Explicit consent is obtained directly from the data subject when sensitive personal information is collected, used, or disclosed, unless a law or regulation specifically requires otherwise. Documents Explicit Consent to Retain Information - Documentation of explicit consent for the collection, use, or disclosure of sensitive personal information is retained in accordance with objectives related to privacy.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "p_3_2",
|
||||
@@ -731,7 +735,7 @@
|
||||
{
|
||||
"Id": "p_4_2",
|
||||
"Name": "P4.2 The entity retains personal information consistent with the entity’s objectives related to privacy",
|
||||
"Description": "Retains Personal Information - Personal information is retained for no longer than necessary to fulfill the stated purposes, unless a law or regulation specifically requires otherwise.Protects Personal Information - Policies and procedures have been implemented to protect personal information from erasure or destruction during the specified retention period of the information.",
|
||||
"Description": "Retains Personal Information - Personal information is retained for no longer than necessary to fulfill the stated purposes, unless a law or regulation specifically requires otherwise. Protects Personal Information - Policies and procedures have been implemented to protect personal information from erasure or destruction during the specified retention period of the information.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "p_4_2",
|
||||
@@ -745,7 +749,7 @@
|
||||
{
|
||||
"Id": "p_4_3",
|
||||
"Name": "P4.3 The entity securely disposes of personal information to meet the entity’s objectives related to privacy",
|
||||
"Description": "Captures, Identifies, and Flags Requests for Deletion - Requests for deletion of personal information are captured, and information related to the requests is identified and flagged for destruction to meet the entity’s objectives related to privacy.Disposes of, Destroys, and Redacts Personal Information - Personal information no longer retained is anonymized, disposed of, or destroyed in a manner that prevents loss, theft, misuse, or unauthorized access.Destroys Personal Information - Policies and procedures are implemented to erase or otherwise destroy personal information that has been identified for destruction.",
|
||||
"Description": "Captures, Identifies, and Flags Requests for Deletion - Requests for deletion of personal information are captured, and information related to the requests is identified and flagged for destruction to meet the entity’s objectives related to privacy. Disposes of, Destroys, and Redacts Personal Information - Personal information no longer retained is anonymized, disposed of, or destroyed in a manner that prevents loss, theft, misuse, or unauthorized access. Destroys Personal Information - Policies and procedures are implemented to erase or otherwise destroy personal information that has been identified for destruction.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "p_4_3",
|
||||
@@ -759,7 +763,7 @@
|
||||
{
|
||||
"Id": "p_5_1",
|
||||
"Name": "P5.1 The entity grants identified and authenticated data subjects the ability to access their stored personal information for review and, upon request, provides physical or electronic copies of that information to data subjects to meet the entity’s objectives related to privacy",
|
||||
"Description": "The entity grants identified and authenticated data subjects the ability to access their stored personal information for review and, upon request, provides physical or electronic copies of that information to data subjects to meet the entity’s objectives related to privacy. If access is denied, data subjects are informed of the denial and reason for such denial, as required, to meet the entity’s objectives related to privacy.Authenticates Data Subjects’ Identity - The identity of data subjects who request access to their personal information is authenticated before they are given access to that information.Permits Data Subjects Access to Their Personal Information - Data subjects are able to determine whether the entity maintains personal information about them and, upon request, may obtain access to their personal information.Provides Understandable Personal Information Within Reasonable Time - Personal information is provided to data subjects in an understandable form, in a reasonable time frame, and at a reasonable cost, if any.Informs Data Subjects If Access Is Denied - When data subjects are denied access to their personal information, the entity informs them of the denial and the reason for the denial in a timely manner, unless prohibited by law or regulation.",
|
||||
"Description": "The entity grants identified and authenticated data subjects the ability to access their stored personal information for review and, upon request, provides physical or electronic copies of that information to data subjects to meet the entity’s objectives related to privacy. If access is denied, data subjects are informed of the denial and reason for such denial, as required, to meet the entity’s objectives related to privacy. Authenticates Data Subjects’ Identity - The identity of data subjects who request access to their personal information is authenticated before they are given access to that information. Permits Data Subjects Access to Their Personal Information - Data subjects are able to determine whether the entity maintains personal information about them and, upon request, may obtain access to their personal information. Provides Understandable Personal Information Within Reasonable Time - Personal information is provided to data subjects in an understandable form, in a reasonable time frame, and at a reasonable cost, if any. Informs Data Subjects If Access Is Denied - When data subjects are denied access to their personal information, the entity informs them of the denial and the reason for the denial in a timely manner, unless prohibited by law or regulation.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "p_5_1",
|
||||
@@ -773,7 +777,7 @@
|
||||
{
|
||||
"Id": "p_5_2",
|
||||
"Name": "P5.2 The entity corrects, amends, or appends personal information based on information provided by data subjects and communicates such information to third parties, as committed or required, to meet the entity’s objectives related to privacy",
|
||||
"Description": "The entity corrects, amends, or appends personal information based on information provided by data subjects and communicates such information to third parties, as committed or required, to meet the entity’s objectives related to privacy. If a request for correction is denied, data subjects are informed of the denial and reason for such denial to meet the entity’s objectives related to privacy.Communicates Denial of Access Requests - Data subjects are informed, in writing, of the reason a request for access to their personal information was denied, the source of the entity’s legal right to deny such access, if applicable, and the individual’s right, if any, to challenge such denial, as specifically permitted or required by law or regulation.Permits Data Subjects to Update or Correct Personal Information - Data subjects are able to update or correct personal information held by the entity. The entity provides such updated or corrected information to third parties that were previously provided with the data subject’s personal information consistent with the entity’s objective related to privacy.Communicates Denial of Correction Requests - Data subjects are informed, in writing, about the reason a request for correction of personal information was denied and how they may appeal.",
|
||||
"Description": "The entity corrects, amends, or appends personal information based on information provided by data subjects and communicates such information to third parties, as committed or required, to meet the entity’s objectives related to privacy. If a request for correction is denied, data subjects are informed of the denial and reason for such denial to meet the entity’s objectives related to privacy. Communicates Denial of Access Requests - Data subjects are informed, in writing, of the reason a request for access to their personal information was denied, the source of the entity’s legal right to deny such access, if applicable, and the individual’s right, if any, to challenge such denial, as specifically permitted or required by law or regulation. Permits Data Subjects to Update or Correct Personal Information - Data subjects are able to update or correct personal information held by the entity. The entity provides such updated or corrected information to third parties that were previously provided with the data subject’s personal information consistent with the entity’s objective related to privacy. Communicates Denial of Correction Requests - Data subjects are informed, in writing, about the reason a request for correction of personal information was denied and how they may appeal.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "p_5_2",
|
||||
@@ -787,7 +791,7 @@
|
||||
{
|
||||
"Id": "p_6_1",
|
||||
"Name": "P6.1 The entity discloses personal information to third parties with the explicit consent of data subjects, and such consent is obtained prior to disclosure to meet the entity’s objectives related to privacy",
|
||||
"Description": "Communicates Privacy Policies to Third Parties - Privacy policies or other specific instructions or requirements for handling personal information are communicated to third parties to whom personal information is disclosed.Discloses Personal Information Only When Appropriate - Personal information is disclosed to third parties only for the purposes for which it was collected or created and only when implicit or explicit consent has been obtained from the data subject, unless a law or regulation specifically requires otherwise.Discloses Personal Information Only to Appropriate Third Parties - Personal information is disclosed only to third parties who have agreements with the entity to protect personal information in a manner consistent with the relevant aspects of the entity’s privacy notice or other specific instructions or requirements. The entity has procedures in place to evaluate that the third parties have effective controls to meet the terms of the agreement, instructions, or requirements.",
|
||||
"Description": "Communicates Privacy Policies to Third Parties - Privacy policies or other specific instructions or requirements for handling personal information are communicated to third parties to whom personal information is disclosed. Discloses Personal Information Only When Appropriate - Personal information is disclosed to third parties only for the purposes for which it was collected or created and only when implicit or explicit consent has been obtained from the data subject, unless a law or regulation specifically requires otherwise. Discloses Personal Information Only to Appropriate Third Parties - Personal information is disclosed only to third parties who have agreements with the entity to protect personal information in a manner consistent with the relevant aspects of the entity’s privacy notice or other specific instructions or requirements. The entity has procedures in place to evaluate that the third parties have effective controls to meet the terms of the agreement, instructions, or requirements.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "p_6_1",
|
||||
@@ -829,7 +833,7 @@
|
||||
{
|
||||
"Id": "p_6_4",
|
||||
"Name": "P6.4 The entity obtains privacy commitments from vendors and other third parties who have access to personal information to meet the entity’s objectives related to privacy",
|
||||
"Description": "The entity obtains privacy commitments from vendors and other third parties who have access to personal information to meet the entity’s objectives related to privacy. The entity assesses those parties’ compliance on a periodic and as-needed basis and takes corrective action, if necessary.Discloses Personal Information Only to Appropriate Third Parties - Personal information is disclosed only to third parties who have agreements with the entity to protect personal information in a manner consistent with the relevant aspects of the entity’s privacy notice or other specific instructions or requirements. The entity has procedures in place to evaluate that the third parties have effective controls to meet the terms of the agreement, instructions, or requirements.Remediates Misuse of Personal Information by a Third Party - The entity takes remedial action in response to misuse of personal information by a third party to whom the entity has transferred such information.",
|
||||
"Description": "The entity obtains privacy commitments from vendors and other third parties who have access to personal information to meet the entity’s objectives related to privacy. The entity assesses those parties’ compliance on a periodic and as-needed basis and takes corrective action, if necessary. Discloses Personal Information Only to Appropriate Third Parties - Personal information is disclosed only to third parties who have agreements with the entity to protect personal information in a manner consistent with the relevant aspects of the entity’s privacy notice or other specific instructions or requirements. The entity has procedures in place to evaluate that the third parties have effective controls to meet the terms of the agreement, instructions, or requirements. Remediates Misuse of Personal Information by a Third Party - The entity takes remedial action in response to misuse of personal information by a third party to whom the entity has transferred such information.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "p_6_4",
|
||||
@@ -843,7 +847,7 @@
|
||||
{
|
||||
"Id": "p_6_5",
|
||||
"Name": "P6.5 The entity obtains commitments from vendors and other third parties with access to personal information to notify the entity in the event of actual or suspected unauthorized disclosures of personal information",
|
||||
"Description": "The entity obtains commitments from vendors and other third parties with access to personal information to notify the entity in the event of actual or suspected unauthorized disclosures of personal information. Such notifications are reported to appropriate personnel and acted on in accordance with established incident response procedures to meet the entity’s objectives related to privacy.Remediates Misuse of Personal Information by a Third Party - The entity takes remedial action in response to misuse of personal information by a third party to whom the entity has transferred such information.Reports Actual or Suspected Unauthorized Disclosures - A process exists for obtaining commitments from vendors and other third parties to report to the entity actual or suspected unauthorized disclosures of personal information.",
|
||||
"Description": "The entity obtains commitments from vendors and other third parties with access to personal information to notify the entity in the event of actual or suspected unauthorized disclosures of personal information. Such notifications are reported to appropriate personnel and acted on in accordance with established incident response procedures to meet the entity’s objectives related to privacy. Remediates Misuse of Personal Information by a Third Party - The entity takes remedial action in response to misuse of personal information by a third party to whom the entity has transferred such information. Reports Actual or Suspected Unauthorized Disclosures - A process exists for obtaining commitments from vendors and other third parties to report to the entity actual or suspected unauthorized disclosures of personal information.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "p_6_5",
|
||||
@@ -899,7 +903,7 @@
|
||||
{
|
||||
"Id": "p_8_1",
|
||||
"Name": "P8.1 The entity implements a process for receiving, addressing, resolving, and communicating the resolution of inquiries, complaints, and disputes from data subjects and others and periodically monitors compliance to meet the entity’s objectives related to privacy",
|
||||
"Description": "The entity implements a process for receiving, addressing, resolving, and communicating the resolution of inquiries, complaints, and disputes from data subjects and others and periodically monitors compliance to meet the entity’s objectives related to privacy. Corrections and other necessary actions related to identified deficiencies are made or taken in a timely manner.Communicates to Data Subjects—Data subjects are informed about how to contact the entity with inquiries, complaints, and disputes.Addresses Inquiries, Complaints, and Disputes - A process is in place to address inquiries, complaints, and disputes.Documents and Communicates Dispute Resolution and Recourse - Each complaint is addressed, and the resolution is documented and communicated to the individual.Documents and Reports Compliance Review Results - Compliance with objectives related to privacy are reviewed and documented, and the results of such reviews are reported to management. If problems are identified, remediation plans are developed and implemented.Documents and Reports Instances of Noncompliance - Instances of noncompliance with objectives related to privacy are documented and reported and, if needed, corrective and disciplinary measures are taken on a timely basis.Performs Ongoing Monitoring - Ongoing procedures are performed for monitoring the effectiveness of controls over personal information and for taking timely corrective actions when necessary.",
|
||||
"Description": "The entity implements a process for receiving, addressing, resolving, and communicating the resolution of inquiries, complaints, and disputes from data subjects and others and periodically monitors compliance to meet the entity’s objectives related to privacy. Corrections and other necessary actions related to identified deficiencies are made or taken in a timely manner. Communicates to Data Subjects—Data subjects are informed about how to contact the entity with inquiries, complaints, and disputes. Addresses Inquiries, Complaints, and Disputes - A process is in place to address inquiries, complaints, and disputes. Documents and Communicates Dispute Resolution and Recourse - Each complaint is addressed, and the resolution is documented and communicated to the individual. Documents and Reports Compliance Review Results - Compliance with objectives related to privacy are reviewed and documented, and the results of such reviews are reported to management. If problems are identified, remediation plans are developed and implemented. Documents and Reports Instances of Noncompliance - Instances of noncompliance with objectives related to privacy are documented and reported and, if needed, corrective and disciplinary measures are taken on a timely basis. Performs Ongoing Monitoring - Ongoing procedures are performed for monitoring the effectiveness of controls over personal information and for taking timely corrective actions when necessary.",
|
||||
"Attributes": [
|
||||
{
|
||||
"ItemId": "p_8_1",
|
||||
|
||||
1750
prowler/compliance/gcp/cis_2.0_gcp.json
Normal file
@@ -1,5 +1,8 @@
|
||||
### Account, Check and/or Region can be * to apply for all the cases
|
||||
### Resources is a list that can have either Regex or Keywords:
|
||||
### Account, Check and/or Region can be * to apply for all the cases.
|
||||
### Resources and tags are lists that can have either Regex or Keywords.
|
||||
### Tags is an optional list that matches on tuples of 'key=value' and are "ANDed" together.
|
||||
### Use an alternation Regex to match one of multiple tags with "ORed" logic.
|
||||
### For each check you can except Accounts, Regions, Resources and/or Tags.
|
||||
########################### ALLOWLIST EXAMPLE ###########################
|
||||
Allowlist:
|
||||
Accounts:
|
||||
@@ -11,11 +14,19 @@ Allowlist:
|
||||
Resources:
|
||||
- "user-1" # Will ignore user-1 in check iam_user_hardware_mfa_enabled
|
||||
- "user-2" # Will ignore user-2 in check iam_user_hardware_mfa_enabled
|
||||
"ec2_*":
|
||||
Regions:
|
||||
- "*"
|
||||
Resources:
|
||||
- "*" # Will ignore every EC2 check in every account and region
|
||||
"*":
|
||||
Regions:
|
||||
- "*"
|
||||
Resources:
|
||||
- "test" # Will ignore every resource containing the string "test" in every account and region
|
||||
- "test"
|
||||
Tags:
|
||||
- "test=test" # Will ignore every resource containing the string "test" and the tags 'test=test' and
|
||||
- "project=test|project=stage" # either of ('project=test' OR project=stage) in account 123456789012 and every region
|
||||
|
||||
"*":
|
||||
Checks:
|
||||
@@ -26,7 +37,43 @@ Allowlist:
|
||||
Resources:
|
||||
- "ci-logs" # Will ignore bucket "ci-logs" AND ALSO bucket "ci-logs-replica" in specified check and regions
|
||||
- "logs" # Will ignore EVERY BUCKET containing the string "logs" in specified check and regions
|
||||
- "[[:alnum:]]+-logs" # Will ignore all buckets containing the terms ci-logs, qa-logs, etc. in specified check and regions
|
||||
- ".+-logs" # Will ignore all buckets containing the terms ci-logs, qa-logs, etc. in specified check and regions
|
||||
"*":
|
||||
Regions:
|
||||
- "*"
|
||||
Resources:
|
||||
- "*"
|
||||
Tags:
|
||||
- "environment=dev" # Will ignore every resource containing the tag 'environment=dev' in every account and region
|
||||
|
||||
"*":
|
||||
Checks:
|
||||
"ecs_task_definitions_no_environment_secrets":
|
||||
Regions:
|
||||
- "*"
|
||||
Resources:
|
||||
- "*"
|
||||
Exceptions:
|
||||
Accounts:
|
||||
- "0123456789012"
|
||||
Regions:
|
||||
- "eu-west-1"
|
||||
- "eu-south-2" # Will ignore every resource in check ecs_task_definitions_no_environment_secrets except the ones in account 0123456789012 located in eu-south-2 or eu-west-1
|
||||
|
||||
"123456789012":
|
||||
Checks:
|
||||
"*":
|
||||
Regions:
|
||||
- "*"
|
||||
Resources:
|
||||
- "*"
|
||||
Exceptions:
|
||||
Resources:
|
||||
- "test"
|
||||
Tags:
|
||||
- "environment=prod" # Will ignore every resource except in account 123456789012 except the ones containing the string "test" and tag environment=prod
|
||||
|
||||
|
||||
|
||||
# EXAMPLE: CONTROL TOWER (to migrate)
|
||||
# When using Control Tower, guardrails prevent access to certain protected resources. The allowlist
|
||||
|
||||
@@ -1,48 +1,51 @@
|
||||
import os
|
||||
import pathlib
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from os import getcwd
|
||||
|
||||
import requests
|
||||
import yaml
|
||||
|
||||
from prowler.lib.logger import logger
|
||||
|
||||
timestamp = datetime.today()
|
||||
timestamp_utc = datetime.now(timezone.utc).replace(tzinfo=timezone.utc)
|
||||
prowler_version = "3.2.1"
|
||||
prowler_version = "3.9.0"
|
||||
html_logo_url = "https://github.com/prowler-cloud/prowler/"
|
||||
html_logo_img = "https://user-images.githubusercontent.com/3985464/113734260-7ba06900-96fb-11eb-82bc-d4f68a1e2710.png"
|
||||
square_logo_img = "https://user-images.githubusercontent.com/38561120/235905862-9ece5bd7-9aa3-4e48-807a-3a9035eb8bfb.png"
|
||||
aws_logo = "https://user-images.githubusercontent.com/38561120/235953920-3e3fba08-0795-41dc-b480-9bea57db9f2e.png"
|
||||
azure_logo = "https://user-images.githubusercontent.com/38561120/235927375-b23e2e0f-8932-49ec-b59c-d89f61c8041d.png"
|
||||
gcp_logo = "https://user-images.githubusercontent.com/38561120/235928332-eb4accdc-c226-4391-8e97-6ca86a91cf50.png"
|
||||
|
||||
orange_color = "\033[38;5;208m"
|
||||
banner_color = "\033[1;92m"
|
||||
|
||||
# Compliance
|
||||
compliance_specification_dir = "./compliance"
|
||||
available_compliance_frameworks = [
|
||||
"ens_rd2022_aws",
|
||||
"cis_1.4_aws",
|
||||
"cis_1.5_aws",
|
||||
"aws_audit_manager_control_tower_guardrails_aws",
|
||||
"aws_foundational_security_best_practices_aws",
|
||||
"cisa_aws",
|
||||
"fedramp_low_revision_4_aws",
|
||||
"fedramp_moderate_revision_4_aws",
|
||||
"ffiec_aws",
|
||||
"gdpr_aws",
|
||||
"gxp_eu_annex_11_aws",
|
||||
"gxp_21_cfr_part_11_aws",
|
||||
"hipaa_aws",
|
||||
"nist_800_53_revision_4_aws",
|
||||
"nist_800_53_revision_5_aws",
|
||||
"nist_800_171_revision_2_aws",
|
||||
"nist_csf_1.1_aws",
|
||||
"pci_3.2.1_aws",
|
||||
"rbi_cyber_security_framework_aws",
|
||||
"soc2_aws",
|
||||
]
|
||||
actual_directory = pathlib.Path(os.path.dirname(os.path.realpath(__file__)))
|
||||
|
||||
|
||||
def get_available_compliance_frameworks():
|
||||
available_compliance_frameworks = []
|
||||
for provider in ["aws", "gcp", "azure"]:
|
||||
with os.scandir(f"{actual_directory}/../compliance/{provider}") as files:
|
||||
for file in files:
|
||||
if file.is_file() and file.name.endswith(".json"):
|
||||
available_compliance_frameworks.append(
|
||||
file.name.removesuffix(".json")
|
||||
)
|
||||
return available_compliance_frameworks
|
||||
|
||||
|
||||
available_compliance_frameworks = get_available_compliance_frameworks()
|
||||
|
||||
|
||||
# AWS services-regions matrix json
|
||||
aws_services_json_file = "aws_regions_by_service.json"
|
||||
|
||||
# gcp_zones_json_file = "gcp_zones.json"
|
||||
|
||||
default_output_directory = getcwd() + "/output"
|
||||
|
||||
output_file_timestamp = timestamp.strftime("%Y%m%d%H%M%S")
|
||||
@@ -50,29 +53,70 @@ timestamp_iso = timestamp.isoformat(sep=" ", timespec="seconds")
|
||||
csv_file_suffix = ".csv"
|
||||
json_file_suffix = ".json"
|
||||
json_asff_file_suffix = ".asff.json"
|
||||
json_ocsf_file_suffix = ".ocsf.json"
|
||||
html_file_suffix = ".html"
|
||||
config_yaml = f"{pathlib.Path(os.path.dirname(os.path.realpath(__file__)))}/config.yaml"
|
||||
default_config_file_path = (
|
||||
f"{pathlib.Path(os.path.dirname(os.path.realpath(__file__)))}/config.yaml"
|
||||
)
|
||||
|
||||
|
||||
def change_config_var(variable, value):
|
||||
def check_current_version():
|
||||
try:
|
||||
with open(config_yaml) as f:
|
||||
doc = yaml.safe_load(f)
|
||||
|
||||
doc[variable] = value
|
||||
|
||||
with open(config_yaml, "w") as f:
|
||||
yaml.dump(doc, f)
|
||||
prowler_version_string = f"Prowler {prowler_version}"
|
||||
release_response = requests.get(
|
||||
"https://api.github.com/repos/prowler-cloud/prowler/tags"
|
||||
)
|
||||
latest_version = release_response.json()[0]["name"]
|
||||
if latest_version != prowler_version:
|
||||
return f"{prowler_version_string} (latest is {latest_version}, upgrade for the latest features)"
|
||||
else:
|
||||
return f"{prowler_version_string} (it is the latest version, yay!)"
|
||||
except Exception as error:
|
||||
logger.error(f"{error.__class__.__name__}: {error}")
|
||||
logger.error(
|
||||
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}] -- {error}"
|
||||
)
|
||||
return f"{prowler_version_string}"
|
||||
|
||||
|
||||
def get_config_var(variable):
|
||||
def change_config_var(variable: str, value: str, audit_info):
|
||||
try:
|
||||
with open(config_yaml) as f:
|
||||
doc = yaml.safe_load(f)
|
||||
|
||||
return doc[variable]
|
||||
if (
|
||||
hasattr(audit_info, "audit_config")
|
||||
and audit_info.audit_config is not None
|
||||
and variable in audit_info.audit_config
|
||||
):
|
||||
audit_info.audit_config[variable] = value
|
||||
return audit_info
|
||||
except Exception as error:
|
||||
logger.error(f"{error.__class__.__name__}: {error}")
|
||||
return ""
|
||||
logger.error(
|
||||
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}] -- {error}"
|
||||
)
|
||||
|
||||
|
||||
def load_and_validate_config_file(provider: str, config_file_path: str) -> dict:
|
||||
"""
|
||||
load_and_validate_config_file reads the Prowler config file in YAML format from the default location or the file passed with the --config-file flag
|
||||
"""
|
||||
try:
|
||||
with open(config_file_path) as f:
|
||||
config = {}
|
||||
config_file = yaml.safe_load(f)
|
||||
|
||||
# Not to introduce a breaking change we have to allow the old format config file without any provider keys
|
||||
# and a new format with a key for each provider to include their configuration values within
|
||||
# Check if the new format is passed
|
||||
if "aws" in config_file or "gcp" in config_file or "azure" in config_file:
|
||||
config = config_file.get(provider, {})
|
||||
else:
|
||||
config = config_file if config_file else {}
|
||||
# Not to break Azure and GCP does not support neither use the old config format
|
||||
if provider in ["azure", "gcp"]:
|
||||
config = {}
|
||||
|
||||
return config
|
||||
|
||||
except Exception as error:
|
||||
logger.critical(
|
||||
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}] -- {error}"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
@@ -1,43 +1,68 @@
|
||||
# AWS EC2 Configuration
|
||||
# aws.ec2_elastic_ip_shodan
|
||||
shodan_api_key: null
|
||||
# aws.ec2_securitygroup_with_many_ingress_egress_rules --> by default is 50 rules
|
||||
max_security_group_rules: 50
|
||||
# aws.ec2_instance_older_than_specific_days --> by default is 6 months (180 days)
|
||||
max_ec2_instance_age_in_days: 180
|
||||
# AWS Configuration
|
||||
aws:
|
||||
# AWS EC2 Configuration
|
||||
# aws.ec2_elastic_ip_shodan
|
||||
shodan_api_key: null
|
||||
# aws.ec2_securitygroup_with_many_ingress_egress_rules --> by default is 50 rules
|
||||
max_security_group_rules: 50
|
||||
# aws.ec2_instance_older_than_specific_days --> by default is 6 months (180 days)
|
||||
max_ec2_instance_age_in_days: 180
|
||||
|
||||
# AWS VPC Configuration (vpc_endpoint_connections_trust_boundaries, vpc_endpoint_services_allowed_principals_trust_boundaries)
|
||||
# Single account environment: No action required. The AWS account number will be automatically added by the checks.
|
||||
# Multi account environment: Any additional trusted account number should be added as a space separated list, e.g.
|
||||
# trusted_account_ids : ["123456789012", "098765432109", "678901234567"]
|
||||
trusted_account_ids: []
|
||||
# AWS VPC Configuration (vpc_endpoint_connections_trust_boundaries, vpc_endpoint_services_allowed_principals_trust_boundaries)
|
||||
# Single account environment: No action required. The AWS account number will be automatically added by the checks.
|
||||
# Multi account environment: Any additional trusted account number should be added as a space separated list, e.g.
|
||||
# trusted_account_ids : ["123456789012", "098765432109", "678901234567"]
|
||||
trusted_account_ids: []
|
||||
|
||||
# AWS Cloudwatch Configuration
|
||||
# aws.cloudwatch_log_group_retention_policy_specific_days_enabled --> by default is 365 days
|
||||
log_group_retention_days: 365
|
||||
# AWS Cloudwatch Configuration
|
||||
# aws.cloudwatch_log_group_retention_policy_specific_days_enabled --> by default is 365 days
|
||||
log_group_retention_days: 365
|
||||
|
||||
# AWS AppStream Session Configuration
|
||||
# aws.appstream_fleet_session_idle_disconnect_timeout
|
||||
max_idle_disconnect_timeout_in_seconds: 600 # 10 Minutes
|
||||
# aws.appstream_fleet_session_disconnect_timeout
|
||||
max_disconnect_timeout_in_seconds: 300 # 5 Minutes
|
||||
# aws.appstream_fleet_maximum_session_duration
|
||||
max_session_duration_seconds: 36000 # 10 Hours
|
||||
# AWS AppStream Session Configuration
|
||||
# aws.appstream_fleet_session_idle_disconnect_timeout
|
||||
max_idle_disconnect_timeout_in_seconds: 600 # 10 Minutes
|
||||
# aws.appstream_fleet_session_disconnect_timeout
|
||||
max_disconnect_timeout_in_seconds: 300 # 5 Minutes
|
||||
# aws.appstream_fleet_maximum_session_duration
|
||||
max_session_duration_seconds: 36000 # 10 Hours
|
||||
|
||||
# AWS Lambda Configuration
|
||||
# aws.awslambda_function_using_supported_runtimes
|
||||
obsolete_lambda_runtimes:
|
||||
[
|
||||
"python3.6",
|
||||
"python2.7",
|
||||
"nodejs4.3",
|
||||
"nodejs4.3-edge",
|
||||
"nodejs6.10",
|
||||
"nodejs",
|
||||
"nodejs8.10",
|
||||
"nodejs10.x",
|
||||
"dotnetcore1.0",
|
||||
"dotnetcore2.0",
|
||||
"dotnetcore2.1",
|
||||
"ruby2.5",
|
||||
]
|
||||
# AWS Lambda Configuration
|
||||
# aws.awslambda_function_using_supported_runtimes
|
||||
obsolete_lambda_runtimes:
|
||||
[
|
||||
"python3.6",
|
||||
"python2.7",
|
||||
"nodejs4.3",
|
||||
"nodejs4.3-edge",
|
||||
"nodejs6.10",
|
||||
"nodejs",
|
||||
"nodejs8.10",
|
||||
"nodejs10.x",
|
||||
"dotnetcore1.0",
|
||||
"dotnetcore2.0",
|
||||
"dotnetcore2.1",
|
||||
"ruby2.5",
|
||||
]
|
||||
|
||||
# AWS Organizations
|
||||
# organizations_scp_check_deny_regions
|
||||
# organizations_enabled_regions: [
|
||||
# 'eu-central-1',
|
||||
# 'eu-west-1',
|
||||
# "us-east-1"
|
||||
# ]
|
||||
organizations_enabled_regions: []
|
||||
organizations_trusted_delegated_administrators: []
|
||||
|
||||
# AWS ECR
|
||||
# ecr_repositories_scan_vulnerabilities_in_latest_image
|
||||
# CRITICAL
|
||||
# HIGH
|
||||
# MEDIUM
|
||||
ecr_repository_vulnerability_minimum_severity: "MEDIUM"
|
||||
|
||||
# Azure Configuration
|
||||
azure:
|
||||
|
||||
# GCP Configuration
|
||||
gcp:
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import functools
|
||||
import importlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
import traceback
|
||||
from pkgutil import walk_packages
|
||||
@@ -24,6 +27,7 @@ except KeyError:
|
||||
except Exception:
|
||||
sys.exit(1)
|
||||
|
||||
import prowler
|
||||
from prowler.lib.utils.utils import open_file, parse_json_file
|
||||
from prowler.providers.common.models import Audit_Metadata
|
||||
from prowler.providers.common.outputs import Provider_Output_Options
|
||||
@@ -90,6 +94,9 @@ def exclude_checks_to_run(checks_to_execute: set, excluded_checks: list) -> set:
|
||||
def exclude_services_to_run(
|
||||
checks_to_execute: set, excluded_services: list, provider: str
|
||||
) -> set:
|
||||
excluded_services = [
|
||||
"awslambda" if service == "lambda" else service for service in excluded_services
|
||||
]
|
||||
# Recover checks from the input services
|
||||
for service in excluded_services:
|
||||
modules = recover_checks_from_provider(provider, service)
|
||||
@@ -108,8 +115,8 @@ def exclude_services_to_run(
|
||||
# Load checks from checklist.json
|
||||
def parse_checks_from_file(input_file: str, provider: str) -> set:
|
||||
checks_to_execute = set()
|
||||
f = open_file(input_file)
|
||||
json_file = parse_json_file(f)
|
||||
with open_file(input_file) as f:
|
||||
json_file = parse_json_file(f)
|
||||
|
||||
for check_name in json_file[provider]:
|
||||
checks_to_execute.add(check_name)
|
||||
@@ -117,62 +124,127 @@ def parse_checks_from_file(input_file: str, provider: str) -> set:
|
||||
return checks_to_execute
|
||||
|
||||
|
||||
# Load checks from custom folder
|
||||
def parse_checks_from_folder(audit_info, input_folder: str, provider: str) -> int:
|
||||
try:
|
||||
imported_checks = 0
|
||||
# Check if input folder is a S3 URI
|
||||
if provider == "aws" and re.search(
|
||||
"^s3://([^/]+)/(.*?([^/]+))/$", input_folder
|
||||
):
|
||||
bucket = input_folder.split("/")[2]
|
||||
key = ("/").join(input_folder.split("/")[3:])
|
||||
s3_reource = audit_info.audit_session.resource("s3")
|
||||
bucket = s3_reource.Bucket(bucket)
|
||||
for obj in bucket.objects.filter(Prefix=key):
|
||||
if not os.path.exists(os.path.dirname(obj.key)):
|
||||
os.makedirs(os.path.dirname(obj.key))
|
||||
bucket.download_file(obj.key, obj.key)
|
||||
input_folder = key
|
||||
# Import custom checks by moving the checks folders to the corresponding services
|
||||
with os.scandir(input_folder) as checks:
|
||||
for check in checks:
|
||||
if check.is_dir():
|
||||
check_module = input_folder + "/" + check.name
|
||||
# Copy checks to specific provider/service folder
|
||||
check_service = check.name.split("_")[0]
|
||||
prowler_dir = prowler.__path__
|
||||
prowler_module = f"{prowler_dir[0]}/providers/{provider}/services/{check_service}/{check.name}"
|
||||
if os.path.exists(prowler_module):
|
||||
shutil.rmtree(prowler_module)
|
||||
shutil.copytree(check_module, prowler_module)
|
||||
imported_checks += 1
|
||||
return imported_checks
|
||||
except Exception as error:
|
||||
logger.critical(
|
||||
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}] -- {error}"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# Load checks from custom folder
|
||||
def remove_custom_checks_module(input_folder: str, provider: str):
|
||||
# Check if input folder is a S3 URI
|
||||
s3_uri = False
|
||||
if provider == "aws" and re.search("^s3://([^/]+)/(.*?([^/]+))/$", input_folder):
|
||||
input_folder = ("/").join(input_folder.split("/")[3:])
|
||||
s3_uri = True
|
||||
|
||||
with os.scandir(input_folder) as checks:
|
||||
for check in checks:
|
||||
if check.is_dir():
|
||||
# Remove imported checks
|
||||
check_service = check.name.split("_")[0]
|
||||
prowler_dir = prowler.__path__
|
||||
prowler_module = f"{prowler_dir[0]}/providers/{provider}/services/{check_service}/{check.name}"
|
||||
if os.path.exists(prowler_module):
|
||||
shutil.rmtree(prowler_module)
|
||||
# If S3 URI, remove the downloaded folders
|
||||
if s3_uri and os.path.exists(input_folder):
|
||||
shutil.rmtree(input_folder)
|
||||
|
||||
|
||||
def list_services(provider: str) -> set():
|
||||
available_services = set()
|
||||
checks_tuple = recover_checks_from_provider(provider)
|
||||
for _, check_path in checks_tuple:
|
||||
# Format: /absolute_path/prowler/providers/{provider}/services/{service_name}/{check_name}
|
||||
service_name = check_path.split("/")[-2]
|
||||
if os.name == "nt":
|
||||
service_name = check_path.split("\\")[-2]
|
||||
else:
|
||||
service_name = check_path.split("/")[-2]
|
||||
available_services.add(service_name)
|
||||
return sorted(available_services)
|
||||
|
||||
|
||||
def list_categories(provider: str, bulk_checks_metadata: dict) -> set():
|
||||
def list_categories(bulk_checks_metadata: dict) -> set():
|
||||
available_categories = set()
|
||||
for check in bulk_checks_metadata.values():
|
||||
for cat in check.Categories:
|
||||
available_categories.add(cat)
|
||||
if cat:
|
||||
available_categories.add(cat)
|
||||
return available_categories
|
||||
|
||||
|
||||
def print_categories(categories: set):
|
||||
categories_num = len(categories)
|
||||
plural_string = f"There are {Fore.YELLOW}{categories_num}{Style.RESET_ALL} available categories: \n"
|
||||
singular_string = f"There is {Fore.YELLOW}{categories_num}{Style.RESET_ALL} available category: \n"
|
||||
plural_string = f"\nThere are {Fore.YELLOW}{categories_num}{Style.RESET_ALL} available categories.\n"
|
||||
singular_string = f"\nThere is {Fore.YELLOW}{categories_num}{Style.RESET_ALL} available category.\n"
|
||||
|
||||
message = plural_string if categories_num > 1 else singular_string
|
||||
print(message)
|
||||
for category in categories:
|
||||
print(f"- {category}")
|
||||
|
||||
print(message)
|
||||
|
||||
|
||||
def print_services(service_list: set):
|
||||
services_num = len(service_list)
|
||||
plural_string = (
|
||||
f"There are {Fore.YELLOW}{services_num}{Style.RESET_ALL} available services: \n"
|
||||
)
|
||||
plural_string = f"\nThere are {Fore.YELLOW}{services_num}{Style.RESET_ALL} available services.\n"
|
||||
singular_string = (
|
||||
f"There is {Fore.YELLOW}{services_num}{Style.RESET_ALL} available service: \n"
|
||||
f"\nThere is {Fore.YELLOW}{services_num}{Style.RESET_ALL} available service.\n"
|
||||
)
|
||||
|
||||
message = plural_string if services_num > 1 else singular_string
|
||||
print(message)
|
||||
|
||||
for service in service_list:
|
||||
print(f"- {service}")
|
||||
|
||||
print(message)
|
||||
|
||||
|
||||
def print_compliance_frameworks(
|
||||
bulk_compliance_frameworks: dict,
|
||||
):
|
||||
frameworks_num = len(bulk_compliance_frameworks.keys())
|
||||
plural_string = f"There are {Fore.YELLOW}{frameworks_num}{Style.RESET_ALL} available Compliance Frameworks: \n"
|
||||
singular_string = f"There is {Fore.YELLOW}{frameworks_num}{Style.RESET_ALL} available Compliance Framework: \n"
|
||||
plural_string = f"\nThere are {Fore.YELLOW}{frameworks_num}{Style.RESET_ALL} available Compliance Frameworks.\n"
|
||||
singular_string = f"\nThere is {Fore.YELLOW}{frameworks_num}{Style.RESET_ALL} available Compliance Framework.\n"
|
||||
message = plural_string if frameworks_num > 1 else singular_string
|
||||
|
||||
print(message)
|
||||
for framework in bulk_compliance_frameworks.keys():
|
||||
print(f"\t- {Fore.YELLOW}{framework}{Style.RESET_ALL}")
|
||||
print(f"- {framework}")
|
||||
|
||||
print(message)
|
||||
|
||||
|
||||
def print_compliance_requirements(
|
||||
@@ -199,6 +271,15 @@ def print_compliance_requirements(
|
||||
)
|
||||
|
||||
|
||||
def list_checks_json(provider: str, check_list: set):
|
||||
try:
|
||||
output = {provider: check_list}
|
||||
return json.dumps(output, indent=2, default=str)
|
||||
except Exception as e:
|
||||
logger.critical(f"{e.__class__.__name__}[{e.__traceback__.tb_lineno}]: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def print_checks(
|
||||
provider: str,
|
||||
check_list: set,
|
||||
@@ -353,6 +434,22 @@ def execute_checks(
|
||||
audit_progress=0,
|
||||
)
|
||||
|
||||
if os.name != "nt":
|
||||
try:
|
||||
from resource import RLIMIT_NOFILE, getrlimit
|
||||
|
||||
# Check ulimit for the maximum system open files
|
||||
soft, _ = getrlimit(RLIMIT_NOFILE)
|
||||
if soft < 4096:
|
||||
logger.warning(
|
||||
f"Your session file descriptors limit ({soft} open files) is below 4096. We recommend to increase it to avoid errors. Solve it running this command `ulimit -n 4096`. For more info visit https://docs.prowler.cloud/en/latest/troubleshooting/"
|
||||
)
|
||||
except Exception as error:
|
||||
logger.error("Unable to retrieve ulimit default settings")
|
||||
logger.error(
|
||||
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
|
||||
# Execution with the --only-logs flag
|
||||
if audit_output_options.only_logs:
|
||||
for check_name in checks_to_execute:
|
||||
@@ -490,6 +587,9 @@ def update_audit_metadata(
|
||||
|
||||
def recover_checks_from_service(service_list: list, provider: str) -> list:
|
||||
checks = set()
|
||||
service_list = [
|
||||
"awslambda" if service == "lambda" else service for service in service_list
|
||||
]
|
||||
for service in service_list:
|
||||
modules = recover_checks_from_provider(provider, service)
|
||||
if not modules:
|
||||
@@ -504,68 +604,3 @@ def recover_checks_from_service(service_list: list, provider: str) -> list:
|
||||
# if service_name in group_list: checks_from_arn.add(check_name)
|
||||
checks.add(check_name)
|
||||
return checks
|
||||
|
||||
|
||||
def get_checks_from_input_arn(audit_resources: list, provider: str) -> set:
|
||||
"""get_checks_from_input_arn gets the list of checks from the input arns"""
|
||||
checks_from_arn = set()
|
||||
# Handle if there are audit resources so only their services are executed
|
||||
if audit_resources:
|
||||
services_without_subservices = ["guardduty", "kms", "s3", "elb"]
|
||||
service_list = set()
|
||||
sub_service_list = set()
|
||||
for resource in audit_resources:
|
||||
service = resource.split(":")[2]
|
||||
sub_service = resource.split(":")[5].split("/")[0].replace("-", "_")
|
||||
|
||||
if (
|
||||
service != "wafv2" and service != "waf"
|
||||
): # WAF Services does not have checks
|
||||
# Parse services when they are different in the ARNs
|
||||
if service == "lambda":
|
||||
service = "awslambda"
|
||||
if service == "elasticloadbalancing":
|
||||
service = "elb"
|
||||
elif service == "logs":
|
||||
service = "cloudwatch"
|
||||
service_list.add(service)
|
||||
|
||||
# Get subservices to execute only applicable checks
|
||||
if service not in services_without_subservices:
|
||||
# Parse some specific subservices
|
||||
if service == "ec2":
|
||||
if sub_service == "security_group":
|
||||
sub_service = "securitygroup"
|
||||
if sub_service == "network_acl":
|
||||
sub_service = "networkacl"
|
||||
if sub_service == "image":
|
||||
sub_service = "ami"
|
||||
if service == "rds":
|
||||
if sub_service == "cluster_snapshot":
|
||||
sub_service = "snapshot"
|
||||
sub_service_list.add(sub_service)
|
||||
else:
|
||||
sub_service_list.add(service)
|
||||
|
||||
checks = recover_checks_from_service(service_list, provider)
|
||||
|
||||
# Filter only checks with audited subservices
|
||||
for check in checks:
|
||||
if any(sub_service in check for sub_service in sub_service_list):
|
||||
if not (sub_service == "policy" and "password_policy" in check):
|
||||
checks_from_arn.add(check)
|
||||
|
||||
# Return final checks list
|
||||
return sorted(checks_from_arn)
|
||||
|
||||
|
||||
def get_regions_from_audit_resources(audit_resources: list) -> list:
|
||||
"""get_regions_from_audit_resources gets the regions from the audit resources arns"""
|
||||
audited_regions = []
|
||||
for resource in audit_resources:
|
||||
region = resource.split(":")[3]
|
||||
if region and region not in audited_regions: # Check if arn has a region
|
||||
audited_regions.append(region)
|
||||
if audited_regions:
|
||||
return audited_regions
|
||||
return None
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import sys
|
||||
|
||||
from prowler.lib.check.compliance_models import (
|
||||
Compliance_Base_Model,
|
||||
Compliance_Requirement,
|
||||
)
|
||||
from prowler.lib.check.models import Check_Report_AWS
|
||||
from pydantic import parse_obj_as
|
||||
|
||||
from prowler.lib.check.compliance_models import Compliance_Base_Model
|
||||
from prowler.lib.check.models import Check_Metadata_Model
|
||||
from prowler.lib.logger import logger
|
||||
|
||||
|
||||
@@ -20,16 +19,7 @@ def update_checks_metadata_with_compliance(
|
||||
compliance_requirements = []
|
||||
# Verify if check is in the requirement
|
||||
if check in requirement.Checks:
|
||||
# Create the Compliance_Requirement
|
||||
requirement = Compliance_Requirement(
|
||||
Id=requirement.Id,
|
||||
Description=requirement.Description,
|
||||
Attributes=requirement.Attributes,
|
||||
Checks=requirement.Checks,
|
||||
)
|
||||
# For the check metadata we don't need the "Checks" key
|
||||
delattr(requirement, "Checks")
|
||||
# Include the requirment into the check's framework requirements
|
||||
# Include the requirement into the check's framework requirements
|
||||
compliance_requirements.append(requirement)
|
||||
# Create the Compliance_Model
|
||||
compliance = Compliance_Base_Model(
|
||||
@@ -62,44 +52,33 @@ def update_checks_metadata_with_compliance(
|
||||
# Include the compliance framework for the check
|
||||
check_compliance.append(compliance)
|
||||
# Create metadata for Manual Control
|
||||
manual_check_metadata = """{
|
||||
"Provider" : "aws",
|
||||
"CheckID" : "manual_check",
|
||||
"CheckTitle" : "Manual Check",
|
||||
"CheckType" : [],
|
||||
"ServiceName" : "",
|
||||
"SubServiceName" : "",
|
||||
"ResourceIdTemplate" : "",
|
||||
"Severity" : "",
|
||||
"ResourceType" : "",
|
||||
"Description" : "",
|
||||
"Risk" : "",
|
||||
"RelatedUrl" : "",
|
||||
manual_check_metadata = {
|
||||
"Provider": "aws",
|
||||
"CheckID": "manual_check",
|
||||
"CheckTitle": "Manual Check",
|
||||
"CheckType": [],
|
||||
"ServiceName": "",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "",
|
||||
"ResourceType": "",
|
||||
"Description": "",
|
||||
"Risk": "",
|
||||
"RelatedUrl": "",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "",
|
||||
"Url": ""
|
||||
}
|
||||
"Code": {"CLI": "", "NativeIaC": "", "Other": "", "Terraform": ""},
|
||||
"Recommendation": {"Text": "", "Url": ""},
|
||||
},
|
||||
"Categories" : [],
|
||||
"Tags" : {},
|
||||
"DependsOn" : [],
|
||||
"RelatedTo" : [],
|
||||
"Notes" : ""
|
||||
}"""
|
||||
manual_check = Check_Report_AWS(manual_check_metadata)
|
||||
manual_check.status = "INFO"
|
||||
manual_check.status_extended = "Manual check"
|
||||
manual_check.resource_id = "manual_check"
|
||||
manual_check.Compliance = check_compliance
|
||||
"Categories": [],
|
||||
"Tags": {},
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "",
|
||||
}
|
||||
manual_check = parse_obj_as(Check_Metadata_Model, manual_check_metadata)
|
||||
# Save it into the check's metadata
|
||||
bulk_checks_metadata["manual_check"] = manual_check
|
||||
bulk_checks_metadata["manual_check"].Compliance = check_compliance
|
||||
|
||||
return bulk_checks_metadata
|
||||
except Exception as e:
|
||||
|
||||