Compare commits

..

554 Commits

Author SHA1 Message Date
Adrián Jesús Peña Rodríguez
221310ba94 fix: update unittest 2025-04-22 17:27:53 +02:00
Adrián Jesús Peña Rodríguez
33135f6c9a chore: update lock files 2025-04-22 17:05:03 +02:00
Adrián Jesús Peña Rodríguez
4aaacc9e16 feat: add bash to debian 2025-04-22 16:12:22 +02:00
Adrián Jesús Peña Rodríguez
165d09768f feat: change api base image to debian 2025-04-22 16:12:22 +02:00
Adrián Jesús Peña Rodríguez
6b8af51c23 fix: update base image 2025-04-22 16:12:08 +02:00
Adrián Jesús Peña Rodríguez
e40591a25f chore: change name 2025-04-22 16:12:08 +02:00
Adrián Jesús Peña Rodríguez
d6ac87341b chore: update changelog and spec 2025-04-22 16:12:08 +02:00
Adrián Jesús Peña Rodríguez
d431af6186 feat: change to domain_id 2025-04-22 16:12:08 +02:00
Adrián Jesús Peña Rodríguez
7b3b728207 feat: add m365 to API 2025-04-22 16:11:47 +02:00
César Arroba
cfab4dcef5 chore: pass labels on PR merge trigger (#7558) 2025-04-22 16:11:47 +02:00
César Arroba
cd48037670 chore: revert pass labels (#7556) 2025-04-22 16:11:47 +02:00
César Arroba
ab7e352029 chore: pass labels as json is required (#7555) 2025-04-22 16:11:47 +02:00
César Arroba
79ce899812 chore: fix merged PR action, incorrect order on payload (#7554) 2025-04-22 16:11:47 +02:00
César Arroba
29d4159b8c chore: pass labels (#7553) 2025-04-22 16:11:47 +02:00
César Arroba
aaf7188365 chore: fix json body (#7552) 2025-04-22 16:11:47 +02:00
César Arroba
6cbba3c5b1 chore: fix trigger (#7551) 2025-04-22 16:11:47 +02:00
César Arroba
9510b4c3ef chore(gha): trigger cloud pull-request when a PR is merged (#7212) 2025-04-22 16:11:47 +02:00
Felix Dreissig
c7754c4331 fix(aws): remove SHA-1 from ACM insecure key algorithms (#7547) 2025-04-22 16:11:47 +02:00
Daniel Barranquero
7800320189 feat(defender): add new check defender_antiphishing_policy_configured (#7453) 2025-04-22 16:11:47 +02:00
Daniel Barranquero
972c88e421 feat(defender): add new check defender_malware_policy_notifications_internal_users_malware_enabled (#7435)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-22 16:11:47 +02:00
Daniel Barranquero
3ee420769a feat(defender): add service and new check defender_malware_policy_common_attachments_filter_enabled (#7425)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-22 16:11:47 +02:00
Daniel Barranquero
f8d9873655 feat(exchange): add new check exchange_mailbox_audit_bypass_disabled (#7418)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-22 16:11:47 +02:00
Daniel Barranquero
3f5508847a feat(exchange): add service and new check exchange_organization_mailbox_auditing_enabled (#7408)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-22 16:11:47 +02:00
Hugo Pereira Brito
ed54b39211 feat(teams): add new check teams_email_sending_to_channel_disabled (#7533)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-22 16:11:47 +02:00
HugoPBrito
a6dd97b6bc feat: pwsh setup and print credentials comprobation 2025-04-21 17:54:12 +02:00
HugoPBrito
b6e1551397 Revert "feat: remove provider_id and adapt logic"
This reverts commit 3d9d118d2c.
2025-04-21 17:49:30 +02:00
HugoPBrito
c8567b5d2b Revert "fix: restore 2 tests"
This reverts commit 361269370a.
2025-04-21 17:49:12 +02:00
HugoPBrito
361269370a fix: restore 2 tests 2025-04-21 15:02:53 +02:00
HugoPBrito
3d9d118d2c feat: remove provider_id and adapt logic 2025-04-21 14:58:13 +02:00
HugoPBrito
b50a91d3e6 feat: enhance json parse logging 2025-04-21 13:23:37 +02:00
HugoPBrito
0843c49475 feat: add tests 2025-04-21 12:52:32 +02:00
HugoPBrito
3fe65b7a03 fix: missing provider_id 2025-04-21 11:40:53 +02:00
HugoPBrito
68369ca54f chore: remove old implementation 2025-04-21 11:31:18 +02:00
HugoPBrito
63f4b4f7d4 feat: ensure pwsh user belongs to tenant 2025-04-16 19:10:57 +02:00
HugoPBrito
754a0748da fix(m365): test_connection 2025-04-16 16:38:15 +02:00
Sergio Garcia
aa3182ebc5 feat(gcp): support CLOUDSDK_AUTH_ACCESS_TOKEN (#7495) 2025-04-16 10:35:04 -04:00
Sergio Garcia
32d27df0ba chore(regions): change interval to weekly (#7539) 2025-04-16 09:35:30 -04:00
Prowler Bot
6439f0a5f3 chore(regions_update): Changes in regions for AWS services (#7538)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-16 09:25:29 -04:00
Sergio Garcia
19476632ff chore(dependabot): change settings (#7536) 2025-04-16 11:26:57 +05:45
Pedro Martín
d4c12e4632 fix(iam): change some logger.info values (#7526)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-15 13:25:37 -04:00
Hugo Pereira Brito
52bd48168f feat: adapt Microsoft365 provider to use PowerShell (#7331)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-15 13:24:09 -04:00
Bogdan A
c0d935e232 docs(gcp): update required permissions for GCP (#7488) 2025-04-15 10:23:45 -04:00
Pepe Fagoaga
24dfd47329 fix(pypi): package name location in pyproject.toml while replicating for prowler-cloud (#7531) 2025-04-15 20:01:27 +05:45
dependabot[bot]
fbae338689 chore(deps): bump python from 3.12.9-alpine3.20 to 3.12.10-alpine3.20 (#7520)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 09:26:04 -04:00
dependabot[bot]
186fd88f8c chore(deps): bump codecov/codecov-action from 5.4.0 to 5.4.2 (#7522)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 09:25:44 -04:00
dependabot[bot]
14ff34c00a chore(deps): bump actions/setup-node from 4.3.0 to 4.4.0 (#7521)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 09:25:23 -04:00
Prowler Bot
a66fa394d3 chore(regions_update): Changes in regions for AWS services (#7527)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-15 09:20:20 -04:00
Pepe Fagoaga
931766fe08 chore(action): Remove cache in PyPI release (#7532) 2025-04-15 18:58:26 +05:45
Pepe Fagoaga
c134914896 revert: fix(findings): increase uid max length to 600 (#7528) 2025-04-15 15:54:32 +05:45
Pepe Fagoaga
25dac080a5 chore(changelog): prepare for 5.5.1 (#7523) 2025-04-15 11:46:20 +05:45
Sergio Garcia
910d39eee4 chore(sdk): update changelog (#7512) 2025-04-15 11:19:50 +05:45
Pepe Fagoaga
d604ae5569 fix(pyproject): Restore packages location (#7510) 2025-04-14 16:50:50 -04:00
Bogdan A
42f46b0fb1 feat(gcp): add check for unused Service Accounts (#7419)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-14 11:53:54 -04:00
Pepe Fagoaga
abb5864224 chore(release): bump for 5.6.0 (#7503) 2025-04-14 11:50:46 -04:00
Prowler Bot
2e2a2bd89a chore(regions_update): Changes in regions for AWS services (#7491)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-14 10:29:19 -04:00
Sergio Garcia
f8ee841921 fix(gcp): handle projects without ID (#7496) 2025-04-14 10:25:54 -04:00
Pedro Martín
ceda8c76d2 feat(azure): add SOC2 compliance framework (#7489) 2025-04-14 10:16:20 -04:00
Pedro Martín
afe0b7443f fix(defender): add default name to contacts (#7483) 2025-04-14 10:16:07 -04:00
Prowler Bot
9b773897d2 chore(regions_update): Changes in regions for AWS services (#7487)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-14 09:53:40 -04:00
Pedro Martín
d6ec4c2c96 feat(sdk): add changelog file (#7499) 2025-04-14 09:22:50 -04:00
Prowler Bot
14ef169e99 chore(regions_update): Changes in regions for AWS services (#7497)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-14 09:22:21 -04:00
Pepe Fagoaga
22141f9706 fix(findings): increase uid max length to 600 (#7498)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-04-14 17:46:13 +05:45
Pablo Lara
a5c6fee5b4 fix: update redirect URL for SSO (#7493) 2025-04-11 18:25:28 +05:45
Pablo Lara
d3a5a5c0a1 fix: resolve social login issue in AuthForm on sign-up page (#7490) 2025-04-11 09:59:10 +02:00
dependabot[bot]
5d81869de4 chore(deps): bump tj-actions/changed-files from 46.0.4 to 46.0.5 (#7486)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 22:31:33 -04:00
Pepe Fagoaga
73ebf95d89 chore(changelog): Prepare for v5.5.0 (#7484) 2025-04-09 20:50:56 +05:45
Sergio Garcia
9f4574f4ff fix: handle errors in AWS and Azure (#7482) 2025-04-09 20:19:38 +05:45
Pedro Martín
cb239b20ab fix(aws): add default session_duration (#7479) 2025-04-09 19:19:17 +05:45
eeche
3ef79588b4 feat(NHN): add NHN cloud provider with 6 checks (#6870)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-09 09:13:24 -04:00
Prowler Bot
61000e386b chore(regions_update): Changes in regions for AWS services (#7478)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-09 09:11:29 -04:00
Pablo Lara
53cb57901f fix: fix TS type for session duration (#7481) 2025-04-09 13:44:53 +02:00
Pedro Martín
993ff4d78e feat(gcp): add SOC2 compliance framework (#7476) 2025-04-08 15:04:08 -04:00
Drew Kerrigan
8fb10fbbf7 fix(ui): Remove UTC from timestamps in app (#7474) 2025-04-08 17:43:44 +02:00
Pablo Lara
11e834f639 feat: update the NextJS version to the latest (#7473) 2025-04-08 17:40:39 +02:00
Prowler Bot
62bf2fbb9c chore(regions_update): Changes in regions for AWS services (#7467)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-08 10:21:42 -04:00
dependabot[bot]
e57930d6c2 chore(deps): bump github/codeql-action from 3.28.13 to 3.28.15 (#7463)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-08 09:38:18 -04:00
Pepe Fagoaga
e0c417a466 fix(action): Use poetry > v2 (#7472) 2025-04-08 18:34:24 +05:45
Sergio Garcia
b55f8efed1 fix: handle errors in AWS, Azure, and GCP (#7456) 2025-04-08 18:05:43 +05:45
Pablo Lara
7cbc60d977 feat: add link with the service status using static icon (#7468) 2025-04-08 12:06:21 +02:00
Adrián Jesús Peña Rodríguez
5b7912b558 fix(provider): disable periodic task on views before deleting (#7466)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-04-08 15:35:22 +05:45
Pedro Martín
57fca3e54d fix(soc2_aws): update compliance and remove some requirements (#7452) 2025-04-07 15:47:19 -04:00
Pedro Martín
e31c27b123 fix(gcp): handle logic for empty project names (#7436) 2025-04-07 11:51:15 -04:00
Sergio Garcia
74f1da818e fix(gcp): ignore redirect balancers and add regional ones (#7442) 2025-04-07 11:47:02 -04:00
Pedro Martín
910cfa601b fix(aws): add resource arn for transit gateways (#7447) 2025-04-07 11:46:53 -04:00
dependabot[bot]
fe321c3f8a chore(deps): bump tj-actions/changed-files from 46.0.3 to 46.0.4 (#7443)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 09:11:54 -04:00
Prowler Bot
43de0d405f chore(regions_update): Changes in regions for AWS services (#7446)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-07 09:11:23 -04:00
dependabot[bot]
ac6ed31c8e chore(deps): bump trufflesecurity/trufflehog from 3.88.22 to 3.88.23 (#7444)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 09:11:07 -04:00
Prowler Bot
9d47437de4 chore(regions_update): Changes in regions for AWS services (#7445)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-07 09:10:49 -04:00
Pablo Lara
eb7a62ff77 refactor: extract common auth headers into reusable helper (#7439) 2025-04-07 08:16:55 +02:00
Pedro Martín
67bc16b46d fix(defender): add default resource name in contacts (#7438) 2025-04-04 09:35:11 -04:00
Sergio Garcia
8552a578a0 fix(aws): solve multiple errors (#7431) 2025-04-04 09:34:58 -04:00
Sergio Garcia
a5d277e045 fix(docs): solve broken links (#7432) 2025-04-04 09:15:48 -04:00
Adrián Jesús Peña Rodríguez
6dbf2ac606 feat: add missing SDK fields to API findings and resources (#7318) 2025-04-04 14:57:49 +02:00
Prowler Bot
b1569ac2f3 chore(regions_update): Changes in regions for AWS services (#7434)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-04 08:36:23 -04:00
dependabot[bot]
3d0145b522 chore(deps): bump trufflesecurity/trufflehog from 3.88.20 to 3.88.22 (#7433)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-04 08:34:51 -04:00
Pedro Martín
44174526d6 docs: add onboarding information step by step for each provider (#7362) 2025-04-04 13:00:43 +02:00
Pablo Lara
0fd395ea83 fix: correct fetch variable name from invitations to roles (#7437) 2025-04-04 12:08:57 +02:00
dependabot[bot]
5e9d4a80a1 chore(deps): bump msgraph-sdk from 1.18.0 to 1.23.0 (#7128)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-04-04 11:27:39 +02:00
Pedro Martín
e4d234fe03 fix(azure): remove resource_name inside the Check_Report (#7420) 2025-04-03 11:35:02 -04:00
Prowler Bot
3202184718 chore(regions_update): Changes in regions for AWS services (#7424)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-03 09:39:00 -04:00
Sergio Garcia
41e576f4f1 fix(gcp): make logging sink check at project level (#7421) 2025-04-03 09:37:46 -04:00
Pepe Fagoaga
d8dce07019 chore(deletion): Add environment variable for batch size (#7423)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-04-03 15:31:13 +05:45
Prowler Bot
2b0a3144c7 chore(regions_update): Changes in regions for AWS services (#7417)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-02 09:59:08 -04:00
dependabot[bot]
62fbce0b5e chore(deps): bump azure-identity from 1.19.0 to 1.21.0 (#7192)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-04-02 11:16:47 +02:00
Pedro Martín
5a59bb335c fix(resources): add the correct id and names for resources (#7410) 2025-04-01 20:30:37 +02:00
Sergio Garcia
2719991630 fix(report): log as error when Resource ID or Name do not exist (#7411) 2025-04-01 20:24:18 +02:00
Daniel Barranquero
6a3b8c4674 feat(entra): add new check entra_admin_users_cloud_only (#7286) 2025-04-01 19:14:15 +02:00
dependabot[bot]
191fbf0177 chore(deps): bump azure-mgmt-applicationinsights from 4.0.0 to 4.1.0 (#7161)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-04-01 14:55:37 +02:00
Víctor Fernández Poyatos
228dd2952a fix(scans): Handle duplicated scan tasks (#7401) 2025-04-01 11:55:14 +02:00
dependabot[bot]
97db38aa25 chore(deps): bump azure-mgmt-containerregistry from 10.3.0 to 12.0.0 (#7025)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-04-01 10:29:31 +02:00
Pedro Martín
dc953a6e22 docs(python): add annotations about Python version (#7402) 2025-03-31 18:14:59 +02:00
Bogdan A
51e796a48d feat(gcp): add check for dormant (unused) SA keys (#7348)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
Co-authored-by: Sergio Garcia <sergargar1@gmail.com>
2025-03-31 18:14:21 +02:00
Hugo Pereira Brito
024f1425df feat(entra): add new check entra_legacy_authentication_blocked (#7240) 2025-03-31 18:12:26 +02:00
Hugo Pereira Brito
a7ed610da9 feat(entra): add new check entra_users_mfa_enabled (#7228) 2025-03-31 17:54:52 +02:00
Hugo Pereira Brito
7ba99f22cd feat(entra): add new check entra_admin_users_phishing_resistant_mfa_enabled (#7211)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-03-31 17:52:28 +02:00
Hugo Pereira Brito
b8ce09ec34 fix(entra): check name and logic of entra_admin_users_have_mfa_enabled (#7230) 2025-03-31 17:50:51 +02:00
Daniel Barranquero
c243110a49 feat(entra): add new check entra_policy_guest_invite_only_for_admin_roles (#7241)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-03-31 14:53:50 +02:00
Daniel Barranquero
ee27636f32 fix(redshift): validation error for Cluster.multi_az (#7381) 2025-03-31 13:55:48 +02:00
dependabot[bot]
f2f41c9c44 chore(deps): bump azure-mgmt-resource from 23.2.0 to 23.3.0 (#7054)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-03-31 13:29:49 +02:00
Daniel Barranquero
9312890e6a feat(entra): add new check entra_policy_guest_users_access_restrictions (#7234) 2025-03-31 12:45:26 +02:00
Daniel Barranquero
9578281b4f feat(entra): add new check entra_policy_restricts_user_consent_for_apps (#7225) 2025-03-31 12:32:51 +02:00
Víctor Fernández Poyatos
08690068fc feat(findings): Handle muted findings in API and UI (#7378)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-03-31 12:25:58 +02:00
Hugo Pereira Brito
e06a33de84 feat(entra): add new check entra_managed_device_required_for_mfa_registration (#7203)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-03-31 12:24:47 +02:00
Prowler Bot
6a3db10fda chore(regions_update): Changes in regions for AWS services (#7395)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-03-31 10:18:53 +02:00
Andoni Alonso
bbed445efa chore(sentry): ignore exception when aws service not available in a region (#7352) 2025-03-31 10:13:19 +02:00
dependabot[bot]
9d65fb0bf2 chore(deps): bump trufflesecurity/trufflehog from 3.88.18 to 3.88.20 (#7394)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 10:12:55 +02:00
Prowler Bot
34f03ca110 chore(regions_update): Changes in regions for AWS services (#7391)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-03-27 11:10:07 +01:00
Daniel Barranquero
87c038f0c2 fix(rds): hundle Certificate rds-ca-2019 not found (#7383) 2025-03-27 11:09:33 +01:00
dependabot[bot]
b3014f03b1 chore(deps): bump actions/setup-python from 5.4.0 to 5.5.0 (#7390)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-27 09:13:50 +01:00
Daniel Barranquero
d39598c9fc fix(stepfunctions): Nonetype object has no attribute level (#7386) 2025-03-26 19:39:27 +01:00
Daniel Barranquero
5ea9106259 fix(fms): resource metadata could not be converted to dict (#7379) 2025-03-26 19:25:00 +01:00
Prowler Bot
bcc0b59de1 chore(regions_update): Changes in regions for AWS services (#7382)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-03-26 12:52:35 +01:00
Daniel Barranquero
5d6ed640f0 fix(vm): handle Nonetype is not iterable for extensions (#7360)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-03-25 12:25:15 +01:00
Sergio Garcia
dd1cc2d025 fix(s3): handle None S3 account public access block (#7350) 2025-03-25 11:39:19 +01:00
Andoni Alonso
52e5cc23e4 fix(storagegateway): describe smb/nfs share per region (#7374) 2025-03-25 10:35:37 +01:00
Pablo Lara
76a8e2be1f chore: tweak for button see findings (#7369) 2025-03-25 09:52:36 +01:00
Andoni Alonso
d989425490 fix(vm): handle NoneType accessing security_profile (#7221) 2025-03-25 09:33:00 +01:00
Hugo Pereira Brito
1e324b7ed2 fix(network): handle Nonetype is not iterable for security groups (#7208) 2025-03-25 09:28:37 +01:00
Sergio Garcia
e68aa62f94 fix(iam): handle none SAML Providers (#7359) 2025-03-25 09:24:32 +01:00
Daniel Barranquero
332b98a1ab fix(iam): handle UnboundLocalError cannot access local variable 'report' (#7361) 2025-03-25 09:22:35 +01:00
Pablo Lara
dd05ef7974 chore(scans): properly enable link to findings when scan is completed (#7368) 2025-03-25 08:45:37 +01:00
dependabot[bot]
d6862766d3 chore(deps): bump github/codeql-action from 3.28.12 to 3.28.13 (#7367)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-25 12:43:02 +05:45
dependabot[bot]
f52d005e2d chore(deps): bump tj-actions/changed-files from 46.0.1 to 46.0.3 (#7363)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-25 12:42:50 +05:45
Víctor Fernández Poyatos
bf475234a5 build(api): Force django-allauth==65.4.1 (#7358) 2025-03-24 17:39:47 +01:00
Pablo Lara
cd5985c056 docs: update readme (#7357) 2025-03-24 15:41:35 +01:00
Pablo Lara
ce33dbf823 chore(findings): apply default filter to show failed findings (#7356) 2025-03-24 15:38:09 +01:00
Pablo Lara
0a9d0688a7 docs(changelog): document addition of download column in scans table … (#7354) 2025-03-24 15:28:13 +01:00
Pablo Lara
24784f2ce5 feat(scans): add download button column for completed scans in table (#7353) 2025-03-24 15:22:36 +01:00
Víctor Fernández Poyatos
7a1e611b88 ref(providers): Refactor provider deletion functions (#7349) 2025-03-24 14:39:14 +01:00
Pepe Fagoaga
3073150008 chore(next): Remove x-powered-by header (#7346) 2025-03-24 16:17:18 +05:45
Jonny
9923def4cb chore(awslambda): update obsolete lambda runtimes (#7330)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-03-24 11:21:01 +01:00
Víctor Fernández Poyatos
a7f612303f feat(compliance): Add endpoint to retrieve compliance overviews metadata (#7333) 2025-03-24 10:34:43 +01:00
Pablo Lara
64c2a2217a docs: update changelog with Next.js security patch (#7339) (#7341) 2025-03-24 09:59:59 +01:00
Pablo Lara
4689d7a952 chore: upgrade Next.js to 14.2.25 to fix auth middleware vulnerability (#7339) 2025-03-24 09:48:41 +01:00
Prowler Bot
87cd143967 chore(regions_update): Changes in regions for AWS services (#7219)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-24 09:46:57 +01:00
Prowler Bot
e37fd05d58 chore(regions_update): Changes in regions for AWS services (#7246)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-24 09:46:26 +01:00
Prowler Bot
acc708bda5 chore(regions_update): Changes in regions for AWS services (#7250)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-24 09:46:08 +01:00
Prowler Bot
c7460bb69c chore(regions_update): Changes in regions for AWS services (#7334)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-03-24 09:35:47 +01:00
Pepe Fagoaga
84b273dab9 fix(action): Use Poetry v2 (#7329) 2025-03-20 18:49:32 +01:00
Prowler Bot
bb7ce2157e chore(regions_update): Changes in regions for AWS services (#7323)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-03-20 18:10:28 +05:45
Pepe Fagoaga
07b9e1d3a4 chore(api): Update CHANGELOG (#7325) 2025-03-20 15:22:00 +05:45
Pepe Fagoaga
96a879d761 fix(scan_id): Read the ID from the Scan object (#7324) 2025-03-20 15:18:31 +05:45
Pepe Fagoaga
283127c3f4 chore(aws-regions): remove backport to v3 (#7319) 2025-03-19 22:14:41 +05:45
dependabot[bot]
beeee80a0b chore(deps): bump github/codeql-action from 3.28.11 to 3.28.12 (#7321)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 22:14:23 +05:45
Pepe Fagoaga
06b62826b4 chore(dependabot): disable for v3 (#7316) 2025-03-19 21:56:52 +05:45
Pedro Martín
d0736af209 fix(gcp): make provider id mandatory in test_connection (#7296) 2025-03-19 18:33:49 +05:45
Pablo Lara
716c8c1a5f docs: add social login images and update documentation (#7314)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-03-19 17:16:37 +05:45
Pepe Fagoaga
e6cdda1bd9 chore(dependabot): Disable for API and UI (#7300) 2025-03-19 14:46:11 +05:45
Pedro Martín
2747a633bc fix(k8s): remove typos from PCI 4.0 (#7294) 2025-03-19 09:31:40 +01:00
Pepe Fagoaga
74118f5cfe chore(social-login): improve copy when not enabled (#7295) 2025-03-19 13:36:22 +05:45
dependabot[bot]
598bdf28bb chore(deps): bump trufflesecurity/trufflehog from 3.88.17 to 3.88.18 (#7297)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 12:31:52 +05:45
Pepe Fagoaga
d75f681c87 chore(security): Configure HTTP Security Headers (#7220)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-03-18 17:49:12 +01:00
Pepe Fagoaga
c7956ede6a chore(security): Add HTTP Security Headers (#7289) 2025-03-18 17:44:57 +01:00
Pablo Lara
64f5a69e84 fix: prevent SSR mismatch in OAuth URL generation (#7288) 2025-03-18 17:22:29 +01:00
dependabot[bot]
bfb15c34b8 chore(deps): bump azure-mgmt-containerservice from 34.0.0 to 34.1.0 (#6989)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-03-18 17:14:25 +01:00
Pablo Lara
638b3ac0cd chore(providers): change wording when adding a new provider (#7280) 2025-03-18 21:50:56 +05:45
Daniel Barranquero
9d6147a037 fix(route53): solve false positive in route53_public_hosted_zones_cloudwatch_logging_enabled (#7201) 2025-03-18 16:54:49 +01:00
Pepe Fagoaga
802c786ac2 fix(test-connection): Handle provider without secret (#7283) 2025-03-18 21:34:36 +05:45
Pepe Fagoaga
c8be8dbd9a fix(aws-regions): Use @prowler-bot as author (#7285) 2025-03-18 20:27:19 +05:45
Pablo Lara
7053b2bb37 chore: add env vars for social login (#7257)
Co-authored-by: Adrián Jesús Peña Rodríguez <adrianjpr@gmail.com>
2025-03-18 13:43:46 +01:00
Prowler Bot
447bf832cd chore(regions_update): Changes in regions for AWS services (#7281)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-18 17:35:44 +05:45
Pablo Lara
7c4571b55e feat(providers): add component to render a link to the documentation (#7282) 2025-03-18 12:05:38 +01:00
dependabot[bot]
eb7c16aba5 chore(deps): bump azure-mgmt-storage from 21.2.1 to 22.1.1 (#7098)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-03-18 11:06:46 +01:00
Adrián Jesús Peña Rodríguez
b09e83b171 chore: add api reference to download report section (#7243) 2025-03-18 14:54:13 +05:45
Hugo Pereira Brito
bb149a30a7 fix(microsoft365): typo Microsoft365NotTenantIdButClientIdAndClienSecretError (#7244) 2025-03-17 21:16:47 +05:45
Pablo Lara
d5be35af49 chore: Rename keyServer and extract to helper (#7256) 2025-03-17 21:11:27 +05:45
Pedro Martín
f6aa56d92b fix(.env): remove spaces (#7255) 2025-03-17 20:48:55 +05:45
Pedro Martín
6a4df15c47 fix(prowler): change from prowler.py to prowler-cli.py (#7253) 2025-03-17 15:44:15 +01:00
Pablo Lara
72de5fdb1b chore: update git ignore file (#7254) 2025-03-17 14:53:58 +01:00
Pedro Martín
a7f55d06af feat(jira): add basic auth method (#7233) 2025-03-17 14:31:35 +01:00
Pepe Fagoaga
97da78d4e7 fix(backport): Use container tagged version (#7252) 2025-03-17 18:19:43 +05:45
Pepe Fagoaga
c4f6161c73 chore(security): Pin actions to the Full-Length Commit SHA (#7249) 2025-03-17 17:11:28 +05:45
Pablo Lara
db7ffea24d chore: add env var for social login (#7251) 2025-03-17 10:23:01 +01:00
Prowler Bot
489b5abf82 chore(regions_update): Changes in regions for AWS services (#7237)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-17 13:47:56 +05:45
Prowler Bot
3a55c2ee07 chore(regions_update): Changes in regions for AWS services (#7245)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-17 12:34:44 +05:45
Pedro Martín
64d866271c fix(scan): add compliance info inside finding (#5649) 2025-03-17 12:18:00 +05:45
Pablo Lara
1ab2a80eab chore: improve UX when social login is not enabled (#7242) 2025-03-15 12:12:30 +01:00
Pablo Lara
89d4c521ba chore(social-login): disable social login buttons when env vars are not set (#7238) 2025-03-14 11:32:22 +01:00
Pablo Lara
f2e19d377a chore(social-login): rename env.vars for social login (#7232) 2025-03-13 17:07:17 +01:00
Pablo Lara
2b7b887b87 chore: social auth is algo in sign-up page (#7231) 2025-03-13 14:20:09 +01:00
Pablo Lara
44c70b5d01 chore: remove unused regions (#7229) 2025-03-13 13:57:16 +01:00
Pablo Lara
7514484c42 chore: change wording for launching a single scan (#7226) 2025-03-13 13:48:01 +01:00
Adrián Jesús Peña Rodríguez
9594c4c99f fix: add a handled response in case local files are missing (#7183) 2025-03-13 13:47:00 +01:00
Pablo Lara
56445c9753 chore: update changelog (#7223) 2025-03-13 13:39:26 +01:00
Adrián Jesús Peña Rodríguez
07419fd5e1 fix(exports): change the way to remove the local export files after s3 upload (#7172) 2025-03-13 13:37:17 +01:00
Pablo Lara
2e4dd12b41 feat(social-login): social login with Google is working (#7218)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-03-13 12:52:30 +01:00
Víctor Fernández Poyatos
fed2046c49 fix(migrations): add through parameter to integration.providers (#7222) 2025-03-13 12:47:34 +01:00
Pepe Fagoaga
db79db4786 fix(pyproject): Rename prowler.py (#7217) 2025-03-13 16:53:38 +05:45
Víctor Fernández Poyatos
6f027e3c57 feat(integrations): Added new endpoints to allow configuring integrations (#7167) 2025-03-12 19:57:55 +05:45
Daniel Barranquero
bdb877009f feat(entra): add new check entra_admin_mfa_enabled_for_administrative_roles (#7181)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-03-12 14:47:29 +01:00
Sergio Garcia
6564ec1ff5 fix(cloudwatch): handle None metric alarms (#7205) 2025-03-12 14:44:36 +01:00
Pedro Martín
443dc067b3 feat(kubernetes): add ISO 27001 2022 compliance framework (#7204) 2025-03-12 14:24:53 +01:00
Hugo Pereira Brito
6221650c5f feat(entra): add new check entra_identity_protection_sign_in_risk_enabled (#7171)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-03-12 13:53:47 +01:00
Andoni Alonso
034d0fd1f4 refactor(check): add docstrings and improve report handling (#7113) 2025-03-12 13:38:42 +01:00
Hugo Pereira Brito
e617ff0460 feat(docs): add microsoft365 configurable checks (#7200) 2025-03-12 12:52:35 +01:00
Hugo Pereira Brito
4b1ed607a7 feat(entra): add new check entra_identity_protection_user_risk_enabled (#7126)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-03-12 12:44:31 +01:00
Pepe Fagoaga
137365a670 chore(poetry): Upgrade to v2 (#7112) 2025-03-12 17:28:34 +05:45
Hugo Pereira Brito
1891a1b24f feat(entra): add new check entra_managed_device_required_for_authentication (#7115)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-03-12 11:34:14 +01:00
Daniel Barranquero
e57e070866 feat(entra): add new check entra_password_hash_sync_enabled (#7061) 2025-03-12 11:31:49 +01:00
dependabot[bot]
66998cd1ad chore(deps): bump google-api-python-client from 2.162.0 to 2.163.0 (#7191)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-12 11:25:24 +01:00
Prowler Bot
c0b1833446 chore(regions_update): Changes in regions for AWS services (#7197)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-12 11:25:06 +01:00
Pablo Lara
329a72c77c chore: update changelog (#7199) 2025-03-12 10:12:33 +01:00
Pablo Lara
2610ee9d0c feat(invitations): Disable editing for accepted invites (#7198) 2025-03-12 10:06:46 +01:00
Pablo Lara
a13ca9034e chore(scans): rename type to trigger (#7196) 2025-03-12 09:47:02 +01:00
Pablo Lara
5d1abb3689 chore: auto refresh if the state is also available (#7195) 2025-03-12 09:33:24 +01:00
Pablo Lara
e1d1c6d154 styles: tweaks styles (#7194) 2025-03-12 09:23:02 +01:00
Pablo Lara
e18e0e7cd4 chore(launch-scan): update wording (#7193) 2025-03-12 08:20:15 +01:00
Pablo Lara
eaf3d07a3f chore: update the changelog (#7190) 2025-03-12 08:15:28 +01:00
Hugo Pereira Brito
c88ae32b7f feat(microsoft365): add new check entra_admin_users_sign_in_frequency_enabled (#7020)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-03-11 19:18:33 +01:00
Pablo Lara
605613e220 feat(scans): allow running a scan once (#7188) 2025-03-11 17:47:47 +01:00
Sergio Garcia
d2772000ec chore(sentry): ignore new exceptions in Sentry (#7187) 2025-03-11 17:46:14 +01:00
Adrián Jesús Peña Rodríguez
42939a79f5 docs: add users, invitations and RBAC (#7109) 2025-03-11 21:59:04 +05:45
Daniel Barranquero
ed17931117 feat(entra): add new check entra_dynamic_group_for_guests_created (#7168)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-03-11 16:21:17 +01:00
Daniel Barranquero
66df5f7a1c chore(providers): enhance Remediation.Code.CLI field from check's metadata (#7094)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
2025-03-11 16:15:58 +01:00
Pedro Martín
fc6e6696e5 feat(gcp): add ISO 27001 2022 compliance framework (#7185) 2025-03-11 15:16:40 +01:00
Sergio Garcia
465748c8a1 chore(sentry): ignore expected errors in GCP API (#7184) 2025-03-11 14:32:37 +01:00
Pedro Martín
e59cd71bbf fix(azure): add remaining checks for reqA.5.25 (#7182) 2025-03-11 14:16:10 +01:00
Daniel Barranquero
8a76fea310 feat(entra): add new check entra_admin_consent_workflow_enabled (#7110) 2025-03-11 13:18:17 +01:00
Adrián Jesús Peña Rodríguez
0e46be54ec docs: add generate_output documentation (#7122)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-03-11 17:23:32 +05:45
Pedro Martín
dc81813fdf fix(ens): remove and change duplicated ids (#7165) 2025-03-11 11:35:31 +01:00
Hugo Pereira Brito
eaa0df16bb refactor(microsoft365): resource metadata assertions (#7169) 2025-03-11 11:30:37 +01:00
Pedro Martín
c23e911028 feat(azure): add ISO 27001 2022 compliance framework (#7170) 2025-03-11 11:29:40 +01:00
dependabot[bot]
06b96a1007 chore(deps): bump tzlocal from 5.3 to 5.3.1 (#7162)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-11 11:17:50 +01:00
Prowler Bot
fa545c591f chore(regions_update): Changes in regions for AWS services (#7177)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-11 11:17:27 +01:00
dependabot[bot]
e828b780c7 chore(deps): bump trufflesecurity/trufflehog from 3.88.15 to 3.88.16 (#7174)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-11 11:16:57 +01:00
Harshit Raj Singh
eca8c5cabd feat(aws): AWS Found Sec Best Practices & PCI DSS v3.2.1 upgrade (#7017)
Co-authored-by: pedrooot <pedromarting3@gmail.com>
2025-03-11 09:31:16 +01:00
Pablo Lara
b7bce6008f fix: tweak z-index for custom inputs (#7166) 2025-03-10 11:55:04 +01:00
Pablo Lara
2fdf89883d feat(scans): improve scan launch provider selection (#7164) 2025-03-10 10:05:33 +01:00
dependabot[bot]
6c5d4bbaaa chore(deps): bump django from 5.1.5 to 5.1.7 in /api (#7145)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-10 09:50:09 +01:00
Gary Mclean
cb2f926d4f fix(azure): correct check title for SQL Server Unrestricted (#7123) 2025-03-07 18:24:24 +01:00
ryan-stavella
12c01b437e fix(metadata): typo in ec2_securitygroup_allow_wide_open_public_ipv4 (#7116) 2025-03-07 15:28:08 +01:00
dependabot[bot]
3253a58942 chore(deps-dev): bump mock from 5.1.0 to 5.2.0 (#7099)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-07 15:01:43 +01:00
Kay Agahd
199f7f14ea fix(doc): event_time has been changed to time_dt but was not documented (#7136) 2025-03-07 14:36:51 +01:00
Andoni Alonso
d42406d765 fix(metadata): match type with check results (#7111) 2025-03-07 14:34:07 +01:00
Kay Agahd
2276ffb1f6 fix(aws): ecs_task_definitions_no_environment_secrets.metadata.json (#7135) 2025-03-07 14:31:03 +01:00
dependabot[bot]
218fb3afb0 chore(deps): bump jinja2 from 3.1.5 to 3.1.6 (#7151)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-07 14:27:29 +01:00
Prowler Bot
a9fb890979 chore(regions_update): Changes in regions for AWS services (#7108)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-07 14:06:28 +01:00
Prowler Bot
54ebf5b455 chore(regions_update): Changes in regions for AWS services (#7119)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-07 14:04:48 +01:00
dependabot[bot]
c9a0475aa8 chore(deps-dev): bump mkdocs-git-revision-date-localized-plugin from 1.3.0 to 1.4.1 (#7129)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-07 14:03:44 +01:00
Prowler Bot
5567d9f88c chore(regions_update): Changes in regions for AWS services (#7131)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-07 13:19:08 +01:00
dependabot[bot]
56f3e661ae chore(deps): bump trufflesecurity/trufflehog from 3.88.14 to 3.88.15 (#7127)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-07 13:17:45 +01:00
César Arroba
1aa4479a10 chore: increase release to 5.5.0 (#7143) 2025-03-07 13:16:24 +01:00
Prowler Bot
7b625d0a91 chore(regions_update): Changes in regions for AWS services (#7146)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-07 13:15:51 +01:00
Pablo Lara
fd0529529d chore: update changelog (#7149) 2025-03-07 11:47:23 +01:00
Pablo Lara
af43191954 fix: tweaks for compliance cards (#7147) 2025-03-07 11:32:58 +01:00
Pablo Lara
2ce2ca7c91 feat: add changelog (#7141) 2025-03-06 16:46:55 +01:00
Víctor Fernández Poyatos
a0fc3db665 fix(overviews): manage overview exceptions and use batch_size with bulk (#7140) 2025-03-06 15:35:29 +01:00
César Arroba
feb458027f chore(ui-gha): delete double quotes on prowler version (#7139) 2025-03-06 19:48:53 +05:45
Pablo Lara
e5a5b7af5c fix(groups): display uid if alias is missing (#7137) 2025-03-06 14:37:36 +01:00
Pablo Lara
ad456ae2fe fix(credentials): adjust helper links to fit width (#7133) 2025-03-06 11:42:26 +01:00
Pepe Fagoaga
690cb51f6c revert(findings): change uid from varchar to text (#7132) 2025-03-06 16:24:35 +05:45
dependabot[bot]
14aaa2f376 chore(deps): bump jinja2 from 3.1.5 to 3.1.6 in /api (#7130)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-06 09:39:24 +01:00
César Arroba
6e47ca2c41 chore(ui-gha): add version prefix (#7125) 2025-03-05 21:13:24 +05:45
Víctor Fernández Poyatos
0d99d2be9b fix(reports): Fix task kwargs and result (#7124) 2025-03-05 21:10:44 +05:45
César Arroba
c322ef00e7 chore(ui): add prowler version on build (#7120) 2025-03-05 20:46:16 +05:45
Pablo Lara
3513421225 feat(compliance): new compliance selector (#7118) 2025-03-05 15:12:10 +01:00
Víctor Fernández Poyatos
b0e6bfbefe chore(api): Update changelog (#7090) 2025-03-04 17:44:34 +01:00
dependabot[bot]
f7a918730e chore(deps-dev): bump pytest from 8.3.4 to 8.3.5 (#7097)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-04 09:16:05 +01:00
Pablo Lara
cef33319c5 chore(ui): update label from 'Select a scan job' to 'Select a cloud p… (#7107) 2025-03-04 09:11:39 +01:00
Pablo Lara
2036a59210 fix(roles): show the correct error message (#7089) 2025-03-03 15:46:02 +01:00
Pablo Lara
e5eccb6227 fix: bug with create role and unlimited visibility checkbox (#7088) 2025-03-03 15:45:39 +01:00
Sergio Garcia
48c2c8567c feat(aws): add fixers for threat detection checks (#7085) 2025-03-03 14:20:23 +01:00
Pablo Lara
bbeef0299f feat(version): add prowler version to the sidebar (#7086) 2025-03-03 13:40:09 +01:00
Pablo Lara
bec5584d63 chore: Update the latest table findings with the most recent changes (#7084) 2025-03-03 13:16:30 +01:00
Pablo Lara
bdc759d34c feat(sidebar): sidebar with new functionalities (#7018) 2025-03-03 12:30:28 +01:00
Prowler Bot
8db442d8ba chore(regions_update): Changes in regions for AWS services (#7067)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-03 09:29:48 +01:00
Sergio Garcia
9e7a0d4175 fix(threat detection): run single threat detection check (#7065) 2025-02-28 13:51:07 +01:00
Pepe Fagoaga
9c33b3f5a9 refactor(stats): Use Finding instead of Check_Report (#7053)
Co-authored-by: pedrooot <pedromarting3@gmail.com>
2025-02-28 10:54:48 +01:00
Pepe Fagoaga
7e7e2c87dc chore(examples): Scan AWS (#7064) 2025-02-28 15:25:10 +05:45
Sergio Garcia
2f741f35a8 chore(gcp): enhance GCP APIs logic (#7046) 2025-02-28 14:55:43 +05:45
dependabot[bot]
c411466df7 chore(deps): bump trufflesecurity/trufflehog from 3.88.13 to 3.88.14 (#7063)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-28 09:10:47 +01:00
Daniel Barranquero
9679939307 feat(m365): add sharepoint service with 4 checks (#7057)
Co-authored-by: MarioRgzLpz <mariorgzlpz1809@gmail.com>
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-27 18:15:17 +01:00
Pedro Martín
8539423b22 feat(docs): add info related with sts assume role and regions (#7062) 2025-02-27 17:40:31 +01:00
Daniel Barranquero
81edafdf09 fix(azure): handle account not supporting Blob (#7060) 2025-02-27 13:20:56 +01:00
Sergio Garcia
e0a262882a fix(ecs): ensure unique finding id in ECS checks (#7059) 2025-02-27 13:02:22 +01:00
Prowler Bot
89237ab99e chore(regions_update): Changes in regions for AWS services (#7056)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-27 11:00:13 +01:00
Hugo Pereira Brito
0f414e451e feat(microsoft365): add new check entra_policy_ensure_default_user_cannot_create_tenants (#6918)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-27 10:31:02 +01:00
Pablo Lara
1180522725 feat(exports): download scan exports (#7006) 2025-02-27 14:08:12 +05:45
Pepe Fagoaga
81c7ebf123 fix(env): UI version must be stable (#7055) 2025-02-27 13:32:53 +05:45
Víctor Fernández Poyatos
258f05e6f4 fix(migrations): Fix migration dependency order (#7051) 2025-02-26 17:26:21 +01:00
Víctor Fernández Poyatos
53efb1c153 feat(labeler): apply label on migration changes (#7052) 2025-02-26 17:03:12 +01:00
Pepe Fagoaga
26014a9705 fix(findings): change uid from varchar to text (#7048) 2025-02-26 21:17:16 +05:45
Víctor Fernández Poyatos
00ef037e45 feat(findings): Add Django management command to populate database with dummy data (#7049) 2025-02-26 16:15:37 +01:00
Adrián Jesús Peña Rodríguez
669ec74e67 feat(export): add API export system (#6878) 2025-02-26 15:49:44 +01:00
dependabot[bot]
c4528200b0 chore(deps-dev): bump black from 24.10.0 to 25.1.0 (#6733)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-26 11:38:09 +01:00
Daniel Barranquero
ba7cd0250a fix(elasticache): improve logic in elasticache_redis_cluster_backup_enabled (#7042) 2025-02-26 10:31:14 +01:00
Rubén De la Torre Vico
c5e97678a1 fix(azure): migrate resource models to avoid using SDK defaults (#6880) 2025-02-26 09:54:53 +01:00
Pedro Martín
337a46cdcc feat(aws): add ISO 27001 2022 compliance framework (#7035)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-26 08:34:08 +01:00
Hugo Pereira Brito
7f74b67f1f chore(iam): enhance iam_role_cross_service_confused_deputy_prevention recommendation (#7023) 2025-02-26 07:37:57 +01:00
Prowler Bot
5dcc48d2e5 chore(regions_update): Changes in regions for AWS services (#7034)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-26 07:30:07 +01:00
Prowler Bot
8b04aab07d chore(regions_update): Changes in regions for AWS services (#7015)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-26 07:29:42 +01:00
dependabot[bot]
eab4f6cf2e chore(deps): bump google-api-python-client from 2.161.0 to 2.162.0 (#7037)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-26 07:25:14 +01:00
Hugo Pereira Brito
7f8d623283 refactor(microsoft365): CheckReportMicrosoft365 and resource metadata (#6952) 2025-02-26 07:24:54 +01:00
Víctor Fernández Poyatos
dbffed8f1f feat(findings): Optimize findings endpoint (#7019) 2025-02-25 12:41:47 +01:00
Pepe Fagoaga
7e3688fdd0 chore(action): Conventional Commit Check (#7033) 2025-02-25 09:51:55 +01:00
dependabot[bot]
2e111e9ad3 chore(deps): bump trufflesecurity/trufflehog from 3.88.12 to 3.88.13 (#7026)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-25 14:34:24 +05:45
Pedro Martín
6d6070ff3f feat(outputs): add sample outputs (#6945) 2025-02-25 14:33:16 +05:45
Pedro Martín
391bbde353 fix(cis): show report table on the CLI (#6979) 2025-02-25 14:28:58 +05:45
Pedro Martín
3c56eb3762 feat(azure): add PCI DSS 4.0 (#6982) 2025-02-25 14:27:50 +05:45
Pedro Martín
7c14ea354b feat(kubernetes): add PCI DSS 4.0 (#7013) 2025-02-25 14:27:14 +05:45
Pedro Martín
c96aad0b77 feat(dashboard): take the latest finding uid by timestamp (#6987) 2025-02-25 14:25:03 +05:45
Víctor Fernández Poyatos
a9dd3e424b feat(tasks): add deletion queue for deletion tasks (#7022) 2025-02-24 18:02:52 +01:00
Pedro Martín
8a144a4046 feat(gcp): add PCI DSS 4.0 (#7010) 2025-02-21 16:19:20 +05:30
Prowler Bot
75f86d7267 chore(regions_update): Changes in regions for AWS services (#7011)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-21 15:37:15 +05:30
dependabot[bot]
bbf875fc2f chore(deps-dev): bump mkdocs-material from 9.6.4 to 9.6.5 (#7007)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-21 14:28:18 +05:30
Raj Chowdhury
59d491f61b fix(typo): solve typo in dashboard.md (#7009) 2025-02-21 14:17:08 +05:30
dependabot[bot]
ed640a1324 chore(deps): bump trufflesecurity/trufflehog from 3.88.11 to 3.88.12 (#7008)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-21 14:16:15 +05:30
César Arroba
e86fbcaef7 feat(api): setup sentry for OSS API (#6874) 2025-02-20 23:08:01 +05:45
Pablo Lara
7f48212054 chore(users): renaming the account now triggers a re-render in the sidebar (#7005) 2025-02-20 16:58:45 +01:00
dependabot[bot]
a2c5c71baf chore(deps): bump python from 3.12.8-alpine3.20 to 3.12.9-alpine3.20 (#6882)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-20 21:11:45 +05:30
dependabot[bot]
b904f81cb9 chore(deps): bump tzlocal from 5.2 to 5.3 (#6932)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-20 21:10:46 +05:30
dependabot[bot]
d64fe374dd chore(deps): bump cryptography from 43.0.1 to 44.0.1 in /api (#7001)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-20 12:55:36 +01:00
Hugo Pereira Brito
fe25e7938e docs(tutorials): update all deprecated poetry shell references (#7002) 2025-02-20 17:04:19 +05:45
Prowler Bot
931df361bf chore(regions_update): Changes in regions for AWS services (#6998)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-20 15:52:36 +05:30
Pedro Martín
d7c45f4aee chore(github): add compliance to PR labeler (#6996) 2025-02-20 14:50:43 +05:30
Pedro Martín
5e5bef581b fix(soc2_aws): remove duplicated checks (#6995) 2025-02-20 14:38:26 +05:30
Hugo Pereira Brito
2d9e95d812 docs(installation): add warning for poetry shell deprecation in README (#6983) 2025-02-20 14:19:35 +05:45
Pablo Lara
e5f979d106 chore(findings): add 'Status Extended' attribute to finding details (#6997) 2025-02-20 09:33:03 +01:00
Sergio Garcia
c7a5815203 fix(deps): update vulnerable cryptography dependency (#6993) 2025-02-20 12:18:15 +05:30
Pedro Martín
03e268722e feat(aws): add PCI DSS 4.0 (#6949) 2025-02-20 11:07:06 +05:30
dependabot[bot]
78a2774329 chore(deps): bump trufflesecurity/trufflehog from 3.88.9 to 3.88.11 (#6988)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-20 11:04:15 +05:30
dependabot[bot]
c1b5ab7f53 chore(deps): bump kubernetes from 32.0.0 to 32.0.1 (#6992)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-20 10:46:19 +05:30
Sergio Garcia
b861d97ad4 fix(report): remove invalid resources in report (#6852) 2025-02-19 21:27:52 +05:45
Pablo Lara
f3abcc9dd6 feat(scans): update the progress for executing scans (#6972) 2025-02-19 16:10:29 +01:00
César Arroba
cab13fe018 chore(gha): trigger API or UI deployment when push to master (#6946) 2025-02-19 18:08:51 +05:45
Prowler Bot
cc4b19c7ce chore(regions_update): Changes in regions for AWS services (#6978) 2025-02-19 11:04:45 +01:00
Pablo Lara
a754d9aee5 fix(roles): handle empty response in deleteRole and ensure revalidation (#6976) 2025-02-19 09:03:49 +01:00
Pedro Martín
22b54b2d8d feat(aws): add compliance CIS 4.0 (#6937) 2025-02-19 08:23:49 +05:30
dependabot[bot]
d12ca6301a chore(deps-dev): bump flake8 from 7.1.1 to 7.1.2 (#6954)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-19 08:09:58 +05:30
Hugo Pereira Brito
bc1b2ad9ab test(cloudfront): add name retrieval test for cloudfront bucket domains (#6969) 2025-02-19 08:08:55 +05:30
Pepe Fagoaga
1782ab1514 fix(ocsf): Adapt for 1.4.0 (#6971) 2025-02-19 08:06:13 +05:30
Prowler Bot
0384fc50e3 chore(regions_update): Changes in regions for AWS services (#6968)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-18 18:40:01 +05:30
dependabot[bot]
cc46dee9ee chore(deps-dev): bump bandit from 1.8.2 to 1.8.3 (#6955)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-18 18:39:10 +05:30
Hugo Pereira Brito
ed5a0ae45a fix(cloudfront): Incorrect bucket name retrievement (#6947) 2025-02-17 17:08:28 +01:00
Prowler Bot
928ccfefb8 chore(regions_update): Changes in regions for AWS services (#6944)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-17 16:55:15 +01:00
dependabot[bot]
7f6bfb7b3e chore(deps): bump trufflesecurity/trufflehog from 3.88.8 to 3.88.9 (#6943)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-17 16:54:52 +01:00
Rubén De la Torre Vico
bcbc9bf675 fix(gcp): Correct false positive when sslMode=ENCRYPTED_ONLY in CloudSQL (#6936) 2025-02-14 15:16:21 -05:00
dependabot[bot]
0ec4366f4c chore(deps): bump google-api-python-client from 2.160.0 to 2.161.0 (#6933)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-14 10:09:33 -05:00
César Arroba
ff72b7eea1 fix(gha): fix short sha step (#6939) 2025-02-14 19:11:26 +05:45
César Arroba
a32ca19251 chore(gha): add tag for api and ui images on push to master (#6920) 2025-02-14 18:01:22 +05:45
Pablo Lara
b79508956a fix(issue pages): apply sorting by default in issue pages (#6934) 2025-02-14 10:32:34 +01:00
dependabot[bot]
d76c5bd658 chore(deps): bump trufflesecurity/trufflehog from 3.88.7 to 3.88.8 (#6931)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-13 18:17:25 -05:00
Kay Agahd
580e11126c fix(aws): codebuild service threw KeyError for projects type CODEPIPELINE (#6919) 2025-02-13 12:22:09 -05:00
Sergio Garcia
736d40546a fix(gcp): handle DNS Managed Zone with no DNSSEC (#6924) 2025-02-13 12:18:50 -05:00
dependabot[bot]
88810d2bb5 chore(deps-dev): bump mkdocs-material from 9.6.3 to 9.6.4 (#6913)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-13 11:36:07 -05:00
Víctor Fernández Poyatos
3a8f4d2ffb feat(social-login): Add social login integration for Google and Github OAuth providers (#6906) 2025-02-13 16:54:38 +01:00
Sergio Garcia
1fe125a65f chore(docs): external K8s cluster Prowler App credentials (#6921) 2025-02-13 09:46:05 -05:00
Kay Agahd
0ff4df0836 fix(aws): SNS threw IndexError if SubscriptionArn is PendingConfirmation (#6896) 2025-02-13 09:34:48 -05:00
Pedro Martín
16b4775e2d fix(gcp): remove typos on CIS 3.0 (#6917) 2025-02-13 13:48:19 +01:00
dependabot[bot]
c3a13b8a29 chore(deps): bump trufflesecurity/trufflehog from 3.88.6 to 3.88.7 (#6915)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-12 19:15:03 -05:00
Sergio Garcia
d1053375b7 fix(aws): handle AccessDenied when retrieving resource policy (#6908)
Co-authored-by: Pedro Martín <pedromarting3@gmail.com>
2025-02-12 15:31:26 -05:00
César Arroba
0fa4538256 fix(gha): fix test build containers on pull requests actions (#6909) 2025-02-12 23:26:54 +05:45
Ogonna Iwunze
738644f288 fix(kms): Amazon KMS API call error handling (#6843)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-12 10:09:15 -05:00
dependabot[bot]
2f80b055ac chore(deps-dev): bump coverage from 7.6.11 to 7.6.12 (#6897)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-12 10:08:26 -05:00
Prowler Bot
fd62a1df10 chore(regions_update): Changes in regions for AWS services (#6900)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-12 10:06:42 -05:00
César Arroba
a85d0ebd0a chore(api): test build container image on pull request (#6850) 2025-02-12 15:44:05 +05:45
César Arroba
2c06902baa chore(ui): test build container image on pull request (#6849) 2025-02-12 15:43:22 +05:45
Pepe Fagoaga
76ac6429fe chore(version): Update version to 5.4.0 (#6894) 2025-02-11 17:51:08 -05:00
dependabot[bot]
43cae66b0d chore(deps-dev): bump coverage from 7.6.10 to 7.6.11 (#6887)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-10 19:30:36 -05:00
dependabot[bot]
dacddecc7d chore(deps): bump trufflesecurity/trufflehog from 3.88.5 to 3.88.6 (#6888)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-10 18:15:25 -05:00
Mario Rodriguez Lopez
dcb9267c2f feat(microsof365): Add documentation and compliance file (#6195)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
Co-authored-by: Daniel Barranquero <74871504+danibarranqueroo@users.noreply.github.com>
2025-02-10 11:13:06 -05:00
Víctor Fernández Poyatos
ff35fd90fa chore(api): Update changelog and specs (#6876) 2025-02-10 12:06:34 +01:00
Víctor Fernández Poyatos
7469377079 chore: Add needed steps for API in PR template (#6875) 2025-02-10 15:20:09 +05:45
Pepe Fagoaga
c8441f8d38 fix(kubernetes): Change UID validation (#6869)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-02-10 14:55:24 +05:45
Pepe Fagoaga
abf4eb0ffc chore: Rename dashboard table latest findings (#6873)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-02-10 09:55:44 +01:00
dependabot[bot]
93717cc830 chore(deps-dev): bump mkdocs-material from 9.6.2 to 9.6.3 (#6871)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-07 18:24:49 -05:00
Sergio Garcia
b629bc81f8 docs(eks): add documentation about EKS onboarding (#6853)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-02-07 10:59:01 -05:00
Pedro Martín
f628897fe1 fix(dashboard): adjust the bar chart display (#6690) 2025-02-07 10:05:30 -05:00
Prowler Bot
54b82a78e3 chore(regions_update): Changes in regions for AWS services (#6858)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-07 10:02:28 -05:00
Víctor Fernández Poyatos
377faf145f feat(findings): Use ArrayAgg and subqueries on metadata endpoint (#6863)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-02-07 19:36:01 +05:45
Kay Agahd
69e316948f fix(aws): key error for detect-secrets (#6710) 2025-02-07 14:48:16 +01:00
Pablo Lara
62cbff4f53 feat: implement new functionality with inserted_at__gte in findings a… (#6864) 2025-02-07 14:25:25 +01:00
Víctor Fernández Poyatos
5582265e9d docs: Add details about user creation in Prowler app (#6862) 2025-02-07 13:29:25 +01:00
dependabot[bot]
fb5ea3c324 chore(deps): bump microsoft-kiota-abstractions from 1.9.1 to 1.9.2 (#6856)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-07 11:07:43 +01:00
Víctor Fernández Poyatos
9b5f676f50 feat(findings): Require date filters for findings endpoints (#6800) 2025-02-07 13:54:55 +05:45
Pranay Girase
88cfc0fa7e fix(typo): typos in Dashboard and Report in HTML (#6847) 2025-02-06 10:42:31 -05:00
Prowler Bot
665bfa2f13 chore(regions_update): Changes in regions for AWS services (#6848)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-06 08:46:32 -05:00
dependabot[bot]
b89b1a64f4 chore(deps): bump trufflesecurity/trufflehog from 3.88.4 to 3.88.5 (#6844)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-05 18:02:42 -05:00
Sergio Garcia
9ba657c261 fix(kms): handle error in DescribeKey function (#6839) 2025-02-05 14:03:31 -05:00
Mario Rodriguez Lopez
bce958b8e6 feat(entra): add new check entra_thirdparty_integrated_apps_not_allowed (#6357)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-05 12:45:48 -05:00
Daniel Barranquero
914012de2b fix(cloudfront): fix false positive in s3 origins (#6823) 2025-02-05 12:39:49 -05:00
Ogonna Iwunze
8d1c476aed feat(kms): add kms_cmk_not_multi_region AWS check (#6794)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-05 11:20:29 -05:00
Gary Mclean
567c729e9e fix(findings) Spelling mistakes correction (#6822) 2025-02-05 10:26:50 -05:00
Kay Agahd
3f03dd20e4 fix(aws) wording of report.status_extended in awslambda_function_not_publicly_accessible (#6824) 2025-02-05 10:23:52 -05:00
Daniel Barranquero
1c778354da fix(directoryservice): handle ClientException (#6781)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-05 10:22:32 -05:00
Prowler Bot
3a149fa459 chore(regions_update): Changes in regions for AWS services (#6821)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-05 09:19:56 -05:00
Mario Rodriguez Lopez
f3b121950d feat(entra): add new entra service for Microsoft365 (#6326)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-04 19:47:14 -05:00
Mario Rodriguez Lopez
43c13b7ba1 feat(microsoft365): add new check admincenter_settings_password_never_expire (#6023)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-04 17:24:11 -05:00
dependabot[bot]
9447b33800 chore(deps): bump kubernetes from 31.0.0 to 32.0.0 (#6678)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-04 17:22:51 -05:00
Hugo Pereira Brito
2934752eeb fix(elasticache): InvalidReplicationGroupStateFault error (#6815)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-04 14:28:31 -05:00
dependabot[bot]
dd6d8c71fd chore(deps-dev): bump moto from 5.0.27 to 5.0.28 (#6804)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-04 12:58:48 -05:00
Pablo Lara
80267c389b style(forms): improve spacing consistency (#6814) 2025-02-04 13:20:24 +01:00
Pablo Lara
acfbaf75d5 chore(forms): improvements to the sign-in and sign-up forms (#6813) 2025-02-04 12:46:07 +01:00
Pedro Martín
5f54377407 chore(aws_audit_manager_control_tower_guardrails): add checks to reqs (#6699) 2025-02-03 14:59:08 -05:00
Drew Kerrigan
552aa64741 docs(): add description of changed and new delta values to prowler app tutorial (#6801) 2025-02-03 20:51:03 +01:00
dependabot[bot]
d64f611f51 chore(deps): bump pytz from 2024.2 to 2025.1 (#6765)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-03 12:48:18 -05:00
dependabot[bot]
a96cc92d77 chore(deps-dev): bump mkdocs-material from 9.5.50 to 9.6.2 (#6799)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-03 11:37:02 -05:00
dependabot[bot]
3858cccc41 chore(deps-dev): bump pylint from 3.3.3 to 3.3.4 (#6721)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-03 10:32:42 -05:00
Pedro Martín
072828512a fix(cis_1.5_aws): add checks to needed reqs (#6695)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-02-03 10:32:20 -05:00
Pedro Martín
a73ffe5642 fix(cis_1.4_aws): add checks to needed reqs (#6696)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-02-03 10:32:10 -05:00
Pablo Lara
8e784a5b6d feat(scans): show scan details right after launch (#6791) 2025-02-03 16:08:47 +01:00
dependabot[bot]
1b6f9332f1 chore(deps): bump trufflesecurity/trufflehog from 3.88.2 to 3.88.4 (#6760)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-03 09:35:53 -05:00
secretcod3r
db8b472729 fix(gcp): fix wrong provider value in check (#6691) 2025-02-03 09:29:08 -05:00
Pedro Martín
867b371522 fix(cis_2.0_aws): add checks to needed reqs (#6694) 2025-02-03 09:28:04 -05:00
dependabot[bot]
c0d7c9fc7d chore(deps): bump google-api-python-client from 2.159.0 to 2.160.0 (#6720)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-03 09:27:17 -05:00
Pablo Lara
bb4685cf90 fix(findings): remove default status filtering (#6784) 2025-02-03 15:20:18 +01:00
Pablo Lara
6a95426749 fix(findings): order findings by inserted_at DESC (#6782) 2025-02-03 11:51:07 +01:00
Víctor Fernández Poyatos
ef6af8e84d feat(schedules): Rework daily schedule to always show the next scan (#6700) 2025-02-03 11:08:27 +01:00
Víctor Fernández Poyatos
763130f253 fix(celery): Kill celery worker process after every task to release memory (#6761) 2025-01-31 19:30:08 +05:45
Hugo Pereira Brito
1256c040e9 fix: microsoft365 mutelist (#6724) 2025-01-31 12:32:39 +01:00
dependabot[bot]
18b7b48a99 chore(deps): bump microsoft-kiota-abstractions from 1.6.8 to 1.9.1 (#6734)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-31 10:07:17 +01:00
Pepe Fagoaga
627c11503f fix(db_event): Handle other events (#6754) 2025-01-30 21:46:43 +05:45
Víctor Fernández Poyatos
712ba84f06 feat(scans): Optimize read queries during scans (#6753) 2025-01-30 20:51:12 +05:45
Pepe Fagoaga
5186e029b3 fix(set_report_color): Add more details to error (#6751) 2025-01-30 20:48:51 +05:45
Pablo Lara
5bfaedf903 fix: Enable hot reloading when using Docker Compose for UI (#6750) 2025-01-30 14:05:39 +01:00
Víctor Fernández Poyatos
5061da6897 feat(findings): Improve /findings/metadata performance (#6748) 2025-01-30 13:31:43 +01:00
Pepe Fagoaga
c159a28016 fix(neptune): correct service name (#6743) 2025-01-30 17:16:18 +05:45
Pepe Fagoaga
82a1b1c921 fix(finding): raise when generating invalid findings (#6738) 2025-01-30 15:59:38 +05:45
Pepe Fagoaga
bf2210d0f4 fix(acm): Key Error DomainName (#6739) 2025-01-30 15:54:31 +05:45
Kay Agahd
8f0772cb94 fix(aws): iam_user_with_temporary_credentials resource in OCSF (#6697)
Co-authored-by: Pepe Fagoaga <pepe@verica.io>
2025-01-30 15:28:21 +05:45
Pepe Fagoaga
5b57079ecd fix(sns): Add region to subscriptions (#6731) 2025-01-30 14:38:21 +05:45
Matt Johnson
350d759517 chore: Update Google Analytics ID across all docs.prowler.com sites. (#6730) 2025-01-30 12:47:01 +05:45
Pablo Lara
edd793c9f5 fix(scans): change label for next scan (#6725) 2025-01-29 10:46:49 +01:00
Víctor Fernández Poyatos
545c2dc685 fix(migrations): Use indexes instead of constraints to define an index (#6722) 2025-01-29 14:24:04 +05:45
Víctor Fernández Poyatos
84955c066c revert: Update Django DB manager to use psycopg3 and connection pooling (#6717) 2025-01-28 22:15:01 +05:45
Víctor Fernández Poyatos
06dd03b170 fix(scan-summaries): Improve efficiency on providers overview (#6716) 2025-01-28 21:56:29 +05:45
Pedro Martín
47bc2ed2dc fix(defender): add field to SecurityContacts (#6693) 2025-01-28 15:52:56 +01:00
Pablo Lara
44281afc54 fix(scans): filters and sorting for scan table (#6713) 2025-01-28 13:26:31 +01:00
Víctor Fernández Poyatos
4d2859d145 fix(scans, findings): Improve API performance ordering by inserted_at instead of id (#6711) 2025-01-28 16:41:58 +05:45
Pablo Lara
45d44a1669 fix: fixed bug when opening finding details while a scan is in progress (#6708) 2025-01-28 06:58:18 +01:00
dependabot[bot]
ddd83b340e chore(deps): bump uuid from 10.0.0 to 11.0.5 in /ui (#6516)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-26 13:39:42 +01:00
Mario Rodriguez Lopez
ccdb54d7c3 feat(m365): add Microsoft 365 provider (#5902)
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-24 13:14:17 -05:00
Rubén De la Torre Vico
bcc246d950 fix(cloudsql): add trusted client certificates case for cloudsql_instance_ssl_connections (#6682) 2025-01-24 10:42:45 -05:00
dependabot[bot]
62139e252a chore(deps): bump azure-mgmt-web from 7.3.1 to 8.0.0 (#6680)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-24 12:40:11 +01:00
dependabot[bot]
86950c3a0a chore(deps): bump msgraph-sdk from 1.17.0 to 1.18.0 (#6679)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-24 10:47:09 +01:00
dependabot[bot]
f4865ef68d chore(deps): bump azure-storage-blob from 12.24.0 to 12.24.1 (#6666)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-24 09:44:16 +01:00
Pepe Fagoaga
ea7209e7ae chore: bump for next minor (#6672) 2025-01-23 13:13:08 -05:00
Hugo Pereira Brito
998c551cf3 fix(cloudwatch): NoneType object is not iterable (#6671) 2025-01-23 12:27:07 -05:00
Paolo Frigo
e6f29b0116 docs: update # of checks, services, frameworks and categories (#6528)
Co-authored-by: Sergio Garcia <sergargar1@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-23 11:11:03 -05:00
Pepe Fagoaga
eb90bb39dc chore(api): Bump to v1.3.0 (#6670) 2025-01-23 21:25:29 +05:45
Pepe Fagoaga
ad189b35ad chore(scan): Remove ._findings (#6667) 2025-01-23 20:43:02 +05:45
Pablo Lara
7d2989a233 chore: adjust DateWithTime component height when used with InfoField (#6669) 2025-01-23 15:18:24 +01:00
Pablo Lara
862137ae7d chore(scans): improve scan details (#6665) 2025-01-23 13:20:41 +01:00
Pedro Martín
c86e082d9a feat(detect-secrets): get secrets plugins from config.yaml (#6544)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-01-23 17:18:19 +05:45
Sergio Garcia
80fe048f97 feat(resource metadata): add resource metadata to JSON OCSF (#6592)
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-01-23 16:06:30 +05:45
dependabot[bot]
f2bffb3ce7 chore(deps): bump azure-mgmt-containerservice from 33.0.0 to 34.0.0 (#6630)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-22 16:37:07 -05:00
dependabot[bot]
cbe2f9eef8 chore(deps): bump azure-mgmt-compute from 33.1.0 to 34.0.0 (#6628)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-22 20:00:56 +01:00
Pepe Fagoaga
688f41f570 fix(templates): Customize principals and add validation (#6655) 2025-01-22 21:47:57 +05:45
Anton Rubets
a29197637e chore(helm): Add prowler helm support (#6580)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-22 10:55:26 -05:00
Prowler Bot
7a2712a37f chore(regions_update): Changes in regions for AWS services (#6652)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-01-22 09:30:03 -05:00
dependabot[bot]
189f5cfd8c chore(deps): bump boto3 from 1.35.94 to 1.35.99 (#6651)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-22 09:29:41 -05:00
Kay Agahd
e509480892 fix: add detector and line number of potential secret (#6654) 2025-01-22 20:13:23 +05:45
Pepe Fagoaga
7f7955351a chore(pre-commit): poetry checks for API and SDK (#6658) 2025-01-22 20:05:26 +05:45
Pepe Fagoaga
46f1db21a8 chore(api): Use prowler from master (#6657) 2025-01-22 20:05:02 +05:45
Pablo Lara
fbe7bc6951 feat(providers): show the cloud formation and terraform template links on the form (#6660) 2025-01-22 14:49:38 +01:00
Pablo Lara
f658507847 feat(providers): make external id field mandatory in the aws role secret form (#6656) 2025-01-22 12:45:31 +01:00
dependabot[bot]
374078683b chore(deps-dev): bump moto from 5.0.16 to 5.0.27 (#6632)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-21 13:56:06 -05:00
dependabot[bot]
114c4e0886 chore(deps): bump botocore from 1.35.94 to 1.35.99 (#6520)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-21 09:17:18 -05:00
Pablo Lara
67c62766d4 fix(filters): fix dynamic filters (#6642) 2025-01-21 13:33:27 +01:00
dependabot[bot]
3f2947158d chore(deps): bump prowler from 5.1.1 to 5.1.4 in /api (#6641)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-21 14:27:59 +05:45
dependabot[bot]
278a7cb356 chore(deps-dev): bump mkdocs-material from 9.5.49 to 9.5.50 (#6631)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-20 18:31:44 -05:00
Rubén De la Torre Vico
890158a79c fix(OCSF): fix OCSF output when timestamp is UNIX format (#6606) 2025-01-20 17:11:28 -05:00
Rubén De la Torre Vico
4dc1602b77 fix: update Azure CIS with existing App checks (#6611) 2025-01-20 15:12:00 -05:00
Kay Agahd
bbba0abac9 fix(aws): list tags for DocumentDB clusters (#6605) 2025-01-20 15:10:58 -05:00
Prowler Bot
d04fd807c6 chore(regions_update): Changes in regions for AWS services (#6599)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-01-20 15:09:35 -05:00
Pablo Lara
3456df4cf1 fix(snippet-id): improve provider ID readability in tables (#6615) 2025-01-20 17:23:19 +01:00
Pablo Lara
f56aaa791e chore(RBAC): add permission's info (#6612) 2025-01-20 16:14:48 +01:00
Adrián Jesús Peña Rodríguez
465a758770 fix(rbac): remove invalid required permission (#6608) 2025-01-20 15:21:52 +01:00
Pablo Lara
0f7c0c1b2c fix(RBAC): tweaks for edit role form (#6609) 2025-01-20 14:09:16 +01:00
Adrián Jesús Peña Rodríguez
bf8d10b6f6 feat(api): restrict the deletion of users, only the user of the request can be deleted (#6607) 2025-01-20 13:26:47 +01:00
Pablo Lara
20d04553d6 fix(RBAC): restore manage_account permission for roles (#6602) 2025-01-20 11:35:29 +01:00
Daniel Barranquero
b56d62e3c4 fix(sqs): fix flaky test (#6593) 2025-01-17 11:48:39 -05:00
Hugo Pereira Brito
9a332dcba1 chore(services): delete all comment headers (#6585) 2025-01-17 08:21:28 -05:00
Hugo Pereira Brito
166d9f8823 fix(apigatewayv2): managed exception NotFoundException (#6576) 2025-01-17 08:17:51 -05:00
Prowler Bot
42f5eed75f chore(regions_update): Changes in regions for AWS services (#6577)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-01-17 08:17:00 -05:00
Rubén De la Torre Vico
01a7db18dd fix: add missing Check_Report_Azure parameters (#6583) 2025-01-17 08:16:43 -05:00
Pablo Lara
d4507465a3 fix(providers): update the label and placeholder based on the cloud provider (#6581) 2025-01-17 12:28:38 +01:00
Pablo Lara
3ac92ed10a fix(findings): remove filter delta_in applied by default (#6578) 2025-01-17 11:03:12 +01:00
Pablo Lara
43c76ca85c feat(findings): add first seen in findings details (#6575) 2025-01-17 10:19:10 +01:00
dependabot[bot]
54d87fa96a chore(deps): bump prowler from 5.0.2 to 5.1.1 in /api (#6573)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-17 13:26:07 +05:45
Daniel Barranquero
f041f17268 fix(gcp): fix flaky tests from dns service (#6569) 2025-01-16 14:49:25 -05:00
dependabot[bot]
31c80a6967 chore(deps): bump msgraph-sdk from 1.16.0 to 1.17.0 (#6547)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-16 12:55:30 -05:00
Rubén De la Torre Vico
783ce136f4 feat(network): extract Network resource metadata automated (#6555)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-16 12:41:02 -05:00
Rubén De la Torre Vico
f829145781 feat(storage): extract Storage resource metadata automated (#6563)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-16 11:44:43 -05:00
Rubén De la Torre Vico
389337f8cd feat(vm): extract VM resource metadata automated (#6564) 2025-01-16 11:16:02 -05:00
Pedro Martín
a0713c2d66 fix(cis): add subsections if needed (#6559) 2025-01-16 11:10:54 -05:00
Rubén De la Torre Vico
f94d3cbce4 feat(sqlserver): extract SQL Server resource metadata automated (#6562) 2025-01-16 10:47:21 -05:00
Daniel Barranquero
8d8994b468 feat(aws): include resource metadata to remaining checks (#6551)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-16 10:44:14 -05:00
Rubén De la Torre Vico
784a9097a5 feat(postgresql): extract PostgreSQL resource metadata automated (#6560) 2025-01-16 10:37:55 -05:00
Pedro Martín
b9601626e3 fix(detect_secrets): refactor logic for detect-secrets (#6537) 2025-01-16 21:15:44 +05:45
Rubén De la Torre Vico
dc80b011f2 feat(policy): extract Policy resource metadata automated (#6558) 2025-01-16 10:29:28 -05:00
Rubén De la Torre Vico
ee7d32d460 feat(entra): extract Entra resource metadata automated (#6542)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-16 10:24:53 -05:00
Rubén De la Torre Vico
43fd9ee94e feat(monitor): extract monitor resource metadata automated (#6554)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-16 10:16:19 -05:00
Víctor Fernández Poyatos
8821a91f3f feat(db): Update Django DB manager to use psycopg3 and connection pooling (#6541) 2025-01-16 15:29:02 +01:00
Rubén De la Torre Vico
98d9256f92 feat(mysql): extract MySQL resource metadata automated (#6556) 2025-01-16 09:24:06 -05:00
Rubén De la Torre Vico
b35495eaa7 feat(keyvault): extract KeyVault resource metadata automated (#6553) 2025-01-16 09:17:36 -05:00
Rubén De la Torre Vico
74d6b614b3 feat(iam): extract IAM resource metadata automated (#6552) 2025-01-16 09:05:23 -05:00
Sergio Garcia
dd63c16a74 fix(gcp): iterate through service projects (#6549)
Co-authored-by: pedrooot <pedromarting3@gmail.com>
2025-01-16 08:52:52 -05:00
Pablo Lara
4280266a96 fix(dep): address compatibility issues (#6543) 2025-01-16 14:28:49 +01:00
Hugo Pereira Brito
b1f02098ff feat(aws): include resource metadata in services from r* to s* (#6536)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-15 18:10:53 -05:00
Pedro Martín
95189b574a feat(gcp): add resource metadata to report (#6500)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-15 18:09:35 -05:00
Hugo Pereira Brito
c5d23503bf feat(aws): include resource metadata in services from a* to b* (#6504)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-15 18:03:37 -05:00
Daniel Barranquero
77950f6069 chore(aws): add resource metadata to services from t to w (#6546) 2025-01-15 17:22:08 -05:00
Daniel Barranquero
ec5f2b3753 chore(aws): add resource metadata to services from f to o (#6545) 2025-01-15 17:15:50 -05:00
Rubén De la Torre Vico
9e7104fb7f feat(defender): extract Defender resource metadata in automated way (#6538) 2025-01-15 12:14:24 -05:00
Rubén De la Torre Vico
6b3b6ca45e feat(appinsights): extract App Insights resource metadata in automated way (#6540) 2025-01-15 11:45:23 -05:00
Hugo Pereira Brito
20b8b0b24e feat: add resource metadata to emr_cluster_account_public_block_enabled (#6539) 2025-01-15 11:44:51 -05:00
Sergio Garcia
4e11540458 feat(kubernetes): add resource metadata to report (#6479) 2025-01-15 11:36:09 -05:00
Hugo Pereira Brito
ee87f2676d feat(aws): include resource metadata in services from d* to e* (#6532)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-15 10:05:04 -05:00
Daniel Barranquero
74a90aab98 feat(aws): add resource metadata to all services starting with c (#6493) 2025-01-15 09:04:19 -05:00
Rubén De la Torre Vico
48ff9a5100 feat(cosmosdb): extract CosmosDB resource metadata in automated way (#6533) 2025-01-15 08:51:48 -05:00
Rubén De la Torre Vico
3dfd578ee5 feat(containerregistry): extract Container Registry resource metadata in automated way (#6530) 2025-01-15 08:51:16 -05:00
Rubén De la Torre Vico
0db46cdc81 feat(azure-app): extract Web App resource metadata in automated way (#6529) 2025-01-15 08:48:36 -05:00
Prowler Bot
fdac58d031 chore(regions_update): Changes in regions for AWS services (#6526)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-01-15 08:46:35 -05:00
dependabot[bot]
df9d4ce856 chore(deps): bump google-api-python-client from 2.158.0 to 2.159.0 (#6521)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-15 08:33:47 -05:00
Pedro Martín
e6ae4e97e8 docs(readme): update pr template to add check for readme (#6531) 2025-01-15 12:12:45 +01:00
Adrián Jesús Peña Rodríguez
10a4c28922 feat(finding): add first_seen attribute (#6460) 2025-01-15 11:25:41 +01:00
dependabot[bot]
8a828c6e51 chore(deps): bump django from 5.1.4 to 5.1.5 in /api (#6519)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-15 10:52:11 +01:00
Víctor Fernández Poyatos
d7b40905ff feat(findings): Add resource_tag filters for findings endpoint (#6527) 2025-01-15 10:30:36 +01:00
Adrián Jesús Peña Rodríguez
f9a3b5f3cd feat(provider-secret): make existing external_id field mandatory (#6510) 2025-01-15 10:14:44 +01:00
Pablo Lara
b73b89242f feat(filters): add resource type filter for findings (#6524) 2025-01-15 08:40:53 +01:00
dependabot[bot]
23a0f6e8de chore(deps-dev): bump eslint-config-prettier from 9.1.0 to 10.0.1 in /ui (#6518)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-15 06:55:25 +01:00
Pedro Martín
87967abc3f feat(kubernetes): add CIS 1.10 compliance (#6508)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-14 14:16:00 -05:00
Rubén De la Torre Vico
ce60c286dc feat(aks): use Check_Report_Azure constructor properly in AKS checks (#6509) 2025-01-14 14:14:02 -05:00
Pepe Fagoaga
90fd9b0eb8 chore(version): set next minor (#6511) 2025-01-14 14:06:24 -05:00
Prowler Bot
ca262a6797 chore(regions_update): Changes in regions for AWS services (#6495)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-14 12:43:44 -05:00
Rubén De la Torre Vico
c056d39775 feat(aisearch): use Check_Report_Azure constructor properly in AISearch checks (#6506) 2025-01-14 12:37:01 -05:00
johannes-engler-mw
1c4426ea4b fix(Azure TDE): add filter for master DB (#6351) 2025-01-14 12:34:52 -05:00
Pedro Martín
36520bd7a1 feat(azure): add CIS 3.0 for Azure (#5226) 2025-01-14 12:07:22 -05:00
Pepe Fagoaga
badf0ace76 feat(prowler-role): Add templates to deploy it in AWS (#6499) 2025-01-14 12:04:20 -05:00
Rubén De la Torre Vico
f1f61249e0 feat(azure): include resource metadata in Check_Report_Azure (#6505) 2025-01-14 11:32:40 -05:00
dependabot[bot]
b371cac18c chore(deps): bump jinja2 from 3.1.4 to 3.1.5 (#6457)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-14 10:03:45 -05:00
Víctor Fernández Poyatos
1846535d8d feat(findings): add /findings/metadata to retrieve dynamic filters information (#6503) 2025-01-14 15:30:03 +01:00
dependabot[bot]
d7d9118b9b chore(deps-dev): bump bandit from 1.8.0 to 1.8.2 (#6485)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-14 08:49:37 -05:00
276 changed files with 9326 additions and 3673 deletions

2
.env
View File

@@ -123,7 +123,7 @@ SENTRY_ENVIRONMENT=local
SENTRY_RELEASE=local
#### Prowler release version ####
NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v5.5.0
NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v5.6.0
# Social login credentials
SOCIAL_GOOGLE_OAUTH_CALLBACK_URL="${AUTH_URL}/api/auth/callback/google"

View File

@@ -9,8 +9,8 @@ updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10
interval: "monthly"
open-pull-requests-limit: 25
target-branch: master
labels:
- "dependencies"
@@ -31,8 +31,8 @@ updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10
interval: "monthly"
open-pull-requests-limit: 25
target-branch: master
labels:
- "dependencies"
@@ -53,46 +53,47 @@ updates:
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
interval: "monthly"
open-pull-requests-limit: 25
target-branch: master
labels:
- "dependencies"
- "docker"
# Dependabot Updates are temporary disabled - 2025/04/15
# v4.6
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
target-branch: v4.6
labels:
- "dependencies"
- "pip"
- "v4"
# - package-ecosystem: "pip"
# directory: "/"
# schedule:
# interval: "weekly"
# open-pull-requests-limit: 10
# target-branch: v4.6
# labels:
# - "dependencies"
# - "pip"
# - "v4"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
target-branch: v4.6
labels:
- "dependencies"
- "github_actions"
- "v4"
# - package-ecosystem: "github-actions"
# directory: "/"
# schedule:
# interval: "weekly"
# open-pull-requests-limit: 10
# target-branch: v4.6
# labels:
# - "dependencies"
# - "github_actions"
# - "v4"
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
target-branch: v4.6
labels:
- "dependencies"
- "docker"
- "v4"
# - package-ecosystem: "docker"
# directory: "/"
# schedule:
# interval: "weekly"
# open-pull-requests-limit: 10
# target-branch: v4.6
# labels:
# - "dependencies"
# - "docker"
# - "v4"
# Dependabot Updates are temporary disabled - 2025/03/19
# v3
@@ -107,13 +108,13 @@ updates:
# - "pip"
# - "v3"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
open-pull-requests-limit: 10
target-branch: v3
labels:
- "dependencies"
- "github_actions"
- "v3"
# - package-ecosystem: "github-actions"
# directory: "/"
# schedule:
# interval: "monthly"
# open-pull-requests-limit: 10
# target-branch: v3
# labels:
# - "dependencies"
# - "github_actions"
# - "v3"

View File

@@ -16,6 +16,7 @@ Please include a summary of the change and which issue is fixed. List any depend
- [ ] Review if code is being documented following this specification https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings
- [ ] Review if backport is needed.
- [ ] Review if is needed to change the [Readme.md](https://github.com/prowler-cloud/prowler/blob/master/README.md)
- [ ] Ensure new entries are added to [CHANGELOG.md](https://github.com/prowler-cloud/prowler/blob/master/prowler/CHANGELOG.md), if applicable.
#### API
- [ ] Verify if API specs need to be regenerated.

View File

@@ -167,7 +167,7 @@ jobs:
- name: Upload coverage reports to Codecov
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0
uses: codecov/codecov-action@ad3126e916f78f00edff4ed0317cf185271ccc2d # v5.4.2
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:

View File

@@ -0,0 +1,34 @@
name: Prowler - Merged Pull Request
on:
pull_request_target:
branches: ['master']
types: ['closed']
jobs:
trigger-cloud-pull-request:
name: Trigger Cloud Pull Request
if: github.event.pull_request.merged == true && github.repository == 'prowler-cloud/prowler'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set short git commit SHA
id: vars
run: |
shortSha=$(git rev-parse --short ${{ github.sha }})
echo "SHORT_SHA=${shortSha}" >> $GITHUB_ENV
- name: Trigger pull request
uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3.0.0
with:
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
repository: ${{ secrets.CLOUD_DISPATCH }}
event-type: prowler-pull-request-merged
client-payload: '{
"PROWLER_COMMIT_SHA": "${{ github.sha }}",
"PROWLER_COMMIT_SHORT_SHA": "${{ env.SHORT_SHA }}",
"PROWLER_PR_TITLE": "${{ github.event.pull_request.title }}",
"PROWLER_PR_LABELS": ${{ toJson(github.event.pull_request.labels.*.name) }},
"PROWLER_PR_BODY": ${{ toJson(github.event.pull_request.body) }}
}'

View File

@@ -21,6 +21,7 @@ on:
paths-ignore:
- 'ui/**'
- 'api/**'
- '.github/**'
pull_request:
branches:
- "master"
@@ -30,6 +31,7 @@ on:
paths-ignore:
- 'ui/**'
- 'api/**'
- '.github/**'
schedule:
- cron: '00 12 * * *'

View File

@@ -34,6 +34,7 @@ jobs:
permissions/**
api/**
ui/**
prowler/CHANGELOG.md
README.md
mkdocs.yml
.backportrc.json
@@ -113,7 +114,7 @@ jobs:
- name: Upload coverage reports to Codecov
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0
uses: codecov/codecov-action@ad3126e916f78f00edff4ed0317cf185271ccc2d # v5.4.2
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:

View File

@@ -7,7 +7,7 @@ on:
env:
RELEASE_TAG: ${{ github.event.release.tag_name }}
PYTHON_VERSION: 3.11
CACHE: "poetry"
# CACHE: "poetry"
jobs:
repository-check:
@@ -74,7 +74,7 @@ jobs:
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: ${{ env.CACHE }}
# cache: ${{ env.CACHE }}
- name: Build Prowler package
run: |

View File

@@ -4,7 +4,7 @@ name: SDK - Refresh AWS services' regions
on:
schedule:
- cron: "0 9 * * *" #runs at 09:00 UTC everyday
- cron: "0 9 * * 1" # runs at 09:00 UTC every Monday
env:
GITHUB_BRANCH: "master"

View File

@@ -31,7 +31,7 @@ jobs:
with:
persist-credentials: false
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies

View File

@@ -1,4 +1,4 @@
FROM python:3.12.9-alpine3.20
FROM python:3.12.10-alpine3.20
LABEL maintainer="https://github.com/prowler-cloud/prowler"

View File

@@ -72,10 +72,10 @@ It contains hundreds of controls covering CIS, NIST 800, NIST CSF, CISA, RBI, Fe
| Provider | Checks | Services | [Compliance Frameworks](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/compliance/) | [Categories](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/misc/#categories) |
|---|---|---|---|---|
| AWS | 564 | 82 | 33 | 10 |
| GCP | 78 | 13 | 7 | 3 |
| Azure | 140 | 18 | 7 | 3 |
| GCP | 79 | 13 | 7 | 3 |
| Azure | 140 | 18 | 8 | 3 |
| Kubernetes | 83 | 7 | 4 | 7 |
| Microsoft365 | 5 | 2 | 1 | 0 |
| M365 | 5 | 2 | 1 | 0 |
| NHN (Unofficial) | 6 | 2 | 1 | 0 |
> You can list the checks, services, compliance frameworks and categories with `prowler <provider> --list-checks`, `prowler <provider> --list-services`, `prowler <provider> --list-compliance` and `prowler <provider> --list-categories`.

View File

@@ -2,6 +2,13 @@
All notable changes to the **Prowler API** are documented in this file.
## [v1.7.0] (UNRELEASED)
### Added
- Added M365 as a new provider [(#7563)](https://github.com/prowler-cloud/prowler/pull/7563).
---
## [v1.6.0] (Prowler v5.5.0)
@@ -46,10 +53,6 @@ All notable changes to the **Prowler API** are documented in this file.
- Handled exception when a provider has no secret in test connection [(#7283)](https://github.com/prowler-cloud/prowler/pull/7283).
### Added
- Support for developing new integrations [(#7167)](https://github.com/prowler-cloud/prowler/pull/7167).
---
## [v1.5.0] (Prowler v5.4.0)

View File

@@ -1,13 +1,34 @@
FROM python:3.12.8-alpine3.20 AS build
FROM python:3.12-slim-bookworm AS build
LABEL maintainer="https://github.com/prowler-cloud/api"
# hadolint ignore=DL3018
RUN apk --no-cache add gcc python3-dev musl-dev linux-headers curl-dev
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc python3-dev bash \
libcurl4-openssl-dev ca-certificates less ncurses-base \
krb5-multidev libgcc-s1 gettext libssl3 \
libstdc++6 tzdata liburcu8 zlib1g libicu72 curl openssh-client \
&& rm -rf /var/lib/apt/lists/*
# Install PowerShell
RUN ARCH=$(uname -m) && \
if [ "$ARCH" = "x86_64" ]; then \
curl -L https://github.com/PowerShell/PowerShell/releases/download/v7.5.0/powershell-7.5.0-linux-x64.tar.gz -o /tmp/powershell.tar.gz ; \
elif [ "$ARCH" = "aarch64" ]; then \
curl -L https://github.com/PowerShell/PowerShell/releases/download/v7.5.0/powershell-7.5.0-linux-arm64.tar.gz -o /tmp/powershell.tar.gz ; \
else \
echo "Unsupported architecture: $ARCH" && exit 1 ; \
fi && \
mkdir -p /opt/microsoft/powershell/7 && \
tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7 && \
chmod +x /opt/microsoft/powershell/7/pwsh && \
ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh && \
rm /tmp/powershell.tar.gz
# Add prowler user
RUN addgroup --gid 1000 prowler && \
adduser --uid 1000 --gid 1000 --disabled-password --gecos "" prowler
RUN apk --no-cache upgrade && \
addgroup -g 1000 prowler && \
adduser -D -u 1000 -G prowler prowler
USER prowler
WORKDIR /home/prowler
@@ -17,7 +38,7 @@ COPY pyproject.toml ./
RUN pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir poetry
COPY src/backend/ ./backend/
COPY src/backend/ ./backend/
ENV PATH="/home/prowler/.local/bin:$PATH"
@@ -30,12 +51,13 @@ COPY docker-entrypoint.sh ./docker-entrypoint.sh
WORKDIR /home/prowler/backend
# Development image
# hadolint ignore=DL3006
FROM build AS dev
USER 0
# hadolint ignore=DL3018
RUN apk --no-cache add curl vim
USER root
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends \
curl vim \
&& rm -rf /var/lib/apt/lists/*
USER prowler

1803
api/poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,7 @@ dependencies = [
"drf-spectacular==0.27.2",
"drf-spectacular-jsonapi==0.5.1",
"gunicorn==23.0.0",
"prowler @ git+https://github.com/prowler-cloud/prowler.git@v5.5",
"prowler @ git+https://github.com/prowler-cloud/prowler.git@master",
"psycopg2-binary==2.9.9",
"pytest-celery[redis] (>=1.0.1,<2.0.0)",
"sentry-sdk[django] (>=2.20.0,<3.0.0)",
@@ -46,6 +46,7 @@ coverage = "7.5.4"
django-silk = "5.3.2"
docker = "7.1.0"
freezegun = "1.5.1"
marshmallow = ">=3.15.0,<4.0.0"
mypy = "1.10.1"
pylint = "3.2.5"
pytest = "8.2.2"

View File

@@ -0,0 +1,28 @@
# Generated by Django 5.1.7 on 2025-04-16 08:47
from django.db import migrations
import api.db_utils
class Migration(migrations.Migration):
dependencies = [
("api", "0016_finding_compliance_resource_details_and_more"),
]
operations = [
migrations.AlterField(
model_name="provider",
name="provider",
field=api.db_utils.ProviderEnumField(
choices=[
("aws", "AWS"),
("azure", "Azure"),
("gcp", "GCP"),
("kubernetes", "Kubernetes"),
("m365", "M365"),
],
default="aws",
),
),
]

View File

@@ -191,6 +191,7 @@ class Provider(RowLevelSecurityProtectedModel):
AZURE = "azure", _("Azure")
GCP = "gcp", _("GCP")
KUBERNETES = "kubernetes", _("Kubernetes")
M365 = "m365", _("M365")
@staticmethod
def validate_aws_uid(value):
@@ -214,6 +215,15 @@ class Provider(RowLevelSecurityProtectedModel):
pointer="/data/attributes/uid",
)
@staticmethod
def validate_m365_uid(value):
if not re.match(r"^[a-zA-Z0-9-]+\.onmicrosoft\.com$", value):
raise ModelValidationError(
detail="M365 tenant ID must be a valid domain.",
code="m365-uid",
pointer="/data/attributes/uid",
)
@staticmethod
def validate_gcp_uid(value):
if not re.match(r"^[a-z][a-z0-9-]{5,29}$", value):

View File

@@ -83,11 +83,13 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
* `aws` - AWS
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
- in: query
name: filter[provider_type__in]
schema:
@@ -99,6 +101,7 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
Multiple values may be separated by commas.
@@ -106,6 +109,7 @@ paths:
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
explode: false
style: form
- in: query
@@ -450,11 +454,13 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
* `aws` - AWS
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
- in: query
name: filter[provider_type__in]
schema:
@@ -466,6 +472,7 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
Multiple values may be separated by commas.
@@ -473,6 +480,7 @@ paths:
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
explode: false
style: form
- in: query
@@ -962,11 +970,13 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
* `aws` - AWS
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
- in: query
name: filter[provider_type__in]
schema:
@@ -978,6 +988,7 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
Multiple values may be separated by commas.
@@ -985,6 +996,7 @@ paths:
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
explode: false
style: form
- in: query
@@ -1395,11 +1407,13 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
* `aws` - AWS
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
- in: query
name: filter[provider_type__in]
schema:
@@ -1411,6 +1425,7 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
Multiple values may be separated by commas.
@@ -1418,6 +1433,7 @@ paths:
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
explode: false
style: form
- in: query
@@ -2047,11 +2063,13 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
* `aws` - AWS
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
- in: query
name: filter[provider_type__in]
schema:
@@ -2063,6 +2081,7 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
Multiple values may be separated by commas.
@@ -2070,6 +2089,7 @@ paths:
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
explode: false
style: form
- in: query
@@ -2204,11 +2224,13 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
* `aws` - AWS
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
- in: query
name: filter[provider_type__in]
schema:
@@ -2220,6 +2242,7 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
Multiple values may be separated by commas.
@@ -2227,6 +2250,7 @@ paths:
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
explode: false
style: form
- in: query
@@ -2377,11 +2401,13 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
* `aws` - AWS
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
- in: query
name: filter[provider_type__in]
schema:
@@ -2393,6 +2419,7 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
Multiple values may be separated by commas.
@@ -2400,6 +2427,7 @@ paths:
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
explode: false
style: form
- in: query
@@ -2863,11 +2891,13 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
* `aws` - AWS
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
- in: query
name: filter[provider__in]
schema:
@@ -3441,11 +3471,13 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
* `aws` - AWS
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
- in: query
name: filter[provider_type__in]
schema:
@@ -3457,6 +3489,7 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
Multiple values may be separated by commas.
@@ -3464,6 +3497,7 @@ paths:
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
explode: false
style: form
- in: query
@@ -4167,11 +4201,13 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
* `aws` - AWS
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
- in: query
name: filter[provider_type__in]
schema:
@@ -4183,6 +4219,7 @@ paths:
- azure
- gcp
- kubernetes
- m365
description: |-
Multiple values may be separated by commas.
@@ -4190,6 +4227,7 @@ paths:
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
explode: false
style: form
- in: query
@@ -8347,6 +8385,33 @@ components:
- client_id
- client_secret
- tenant_id
- type: object
title: M365 Static Credentials
properties:
client_id:
type: string
description: The Azure application (client) ID for authentication
in Azure AD.
client_secret:
type: string
description: The client secret associated with the application
(client) ID, providing secure access.
tenant_id:
type: string
description: The Azure tenant ID, representing the directory
where the application is registered.
user:
type: email
description: User microsoft email address.
encrypted_password:
type: string
description: User encrypted password.
required:
- client_id
- client_secret
- tenant_id
- user
- encrypted_password
- type: object
title: GCP Static Credentials
properties:
@@ -8814,12 +8879,14 @@ components:
- azure
- gcp
- kubernetes
- m365
type: string
description: |-
* `aws` - AWS
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
uid:
type: string
title: Unique identifier for the provider, set by the provider
@@ -8926,12 +8993,14 @@ components:
- azure
- gcp
- kubernetes
- m365
type: string
description: |-
* `aws` - AWS
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
uid:
type: string
title: Unique identifier for the provider, set by the provider
@@ -8969,12 +9038,14 @@ components:
- azure
- gcp
- kubernetes
- m365
type: string
description: |-
* `aws` - AWS
* `azure` - Azure
* `gcp` - GCP
* `kubernetes` - Kubernetes
* `m365` - M365
uid:
type: string
minLength: 3
@@ -9559,6 +9630,33 @@ components:
- client_id
- client_secret
- tenant_id
- type: object
title: M365 Static Credentials
properties:
client_id:
type: string
description: The Azure application (client) ID for authentication
in Azure AD.
client_secret:
type: string
description: The client secret associated with the application
(client) ID, providing secure access.
tenant_id:
type: string
description: The Azure tenant ID, representing the directory where
the application is registered.
user:
type: email
description: User microsoft email address.
encrypted_password:
type: string
description: User encrypted password.
required:
- client_id
- client_secret
- tenant_id
- user
- encrypted_password
- type: object
title: GCP Static Credentials
properties:
@@ -9741,6 +9839,33 @@ components:
- client_id
- client_secret
- tenant_id
- type: object
title: M365 Static Credentials
properties:
client_id:
type: string
description: The Azure application (client) ID for authentication
in Azure AD.
client_secret:
type: string
description: The client secret associated with the application
(client) ID, providing secure access.
tenant_id:
type: string
description: The Azure tenant ID, representing the directory
where the application is registered.
user:
type: email
description: User microsoft email address.
encrypted_password:
type: string
description: User encrypted password.
required:
- client_id
- client_secret
- tenant_id
- user
- encrypted_password
- type: object
title: GCP Static Credentials
properties:
@@ -9939,6 +10064,33 @@ components:
- client_id
- client_secret
- tenant_id
- type: object
title: M365 Static Credentials
properties:
client_id:
type: string
description: The Azure application (client) ID for authentication
in Azure AD.
client_secret:
type: string
description: The client secret associated with the application
(client) ID, providing secure access.
tenant_id:
type: string
description: The Azure tenant ID, representing the directory where
the application is registered.
user:
type: email
description: User microsoft email address.
encrypted_password:
type: string
description: User encrypted password.
required:
- client_id
- client_secret
- tenant_id
- user
- encrypted_password
- type: object
title: GCP Static Credentials
properties:

View File

@@ -92,3 +92,31 @@ class TestResourceModel:
assert len(resource.tags.filter(tenant_id=tenant_id)) == 0
assert resource.get_tags(tenant_id=tenant_id) == {}
# @pytest.mark.django_db
# class TestFindingModel:
# def test_add_finding_with_long_uid(
# self, providers_fixture, scans_fixture, resources_fixture
# ):
# provider, *_ = providers_fixture
# tenant_id = provider.tenant_id
# long_uid = "1" * 500
# _ = Finding.objects.create(
# tenant_id=tenant_id,
# uid=long_uid,
# delta=Finding.DeltaChoices.NEW,
# check_metadata={},
# status=StatusChoices.PASS,
# status_extended="",
# severity="high",
# impact="high",
# raw_result={},
# check_id="test_check",
# scan=scans_fixture[0],
# first_seen_at=None,
# muted=False,
# compliance={},
# )
# assert Finding.objects.filter(uid=long_uid).exists()

View File

@@ -19,6 +19,7 @@ from prowler.providers.aws.aws_provider import AwsProvider
from prowler.providers.azure.azure_provider import AzureProvider
from prowler.providers.gcp.gcp_provider import GcpProvider
from prowler.providers.kubernetes.kubernetes_provider import KubernetesProvider
from prowler.providers.m365.m365_provider import M365Provider
class TestMergeDicts:
@@ -104,6 +105,7 @@ class TestReturnProwlerProvider:
(Provider.ProviderChoices.GCP.value, GcpProvider),
(Provider.ProviderChoices.AZURE.value, AzureProvider),
(Provider.ProviderChoices.KUBERNETES.value, KubernetesProvider),
(Provider.ProviderChoices.M365.value, M365Provider),
],
)
def test_return_prowler_provider(self, provider_type, expected_provider):
@@ -176,6 +178,10 @@ class TestGetProwlerProviderKwargs:
Provider.ProviderChoices.KUBERNETES.value,
{"context": "provider_uid"},
),
(
Provider.ProviderChoices.M365.value,
{},
),
],
)
def test_get_prowler_provider_kwargs(self, provider_type, expected_extra_kwargs):

View File

@@ -11,6 +11,7 @@ from prowler.providers.azure.azure_provider import AzureProvider
from prowler.providers.common.models import Connection
from prowler.providers.gcp.gcp_provider import GcpProvider
from prowler.providers.kubernetes.kubernetes_provider import KubernetesProvider
from prowler.providers.m365.m365_provider import M365Provider
class CustomOAuth2Client(OAuth2Client):
@@ -51,14 +52,14 @@ def merge_dicts(default_dict: dict, replacement_dict: dict) -> dict:
def return_prowler_provider(
provider: Provider,
) -> [AwsProvider | AzureProvider | GcpProvider | KubernetesProvider]:
) -> [AwsProvider | AzureProvider | GcpProvider | KubernetesProvider | M365Provider]:
"""Return the Prowler provider class based on the given provider type.
Args:
provider (Provider): The provider object containing the provider type and associated secrets.
Returns:
AwsProvider | AzureProvider | GcpProvider | KubernetesProvider: The corresponding provider class.
AwsProvider | AzureProvider | GcpProvider | KubernetesProvider | M365Provider: The corresponding provider class.
Raises:
ValueError: If the provider type specified in `provider.provider` is not supported.
@@ -72,6 +73,8 @@ def return_prowler_provider(
prowler_provider = AzureProvider
case Provider.ProviderChoices.KUBERNETES.value:
prowler_provider = KubernetesProvider
case Provider.ProviderChoices.M365.value:
prowler_provider = M365Provider
case _:
raise ValueError(f"Provider type {provider.provider} not supported")
return prowler_provider
@@ -104,15 +107,15 @@ def get_prowler_provider_kwargs(provider: Provider) -> dict:
def initialize_prowler_provider(
provider: Provider,
) -> AwsProvider | AzureProvider | GcpProvider | KubernetesProvider:
) -> AwsProvider | AzureProvider | GcpProvider | KubernetesProvider | M365Provider:
"""Initialize a Prowler provider instance based on the given provider type.
Args:
provider (Provider): The provider object containing the provider type and associated secrets.
Returns:
AwsProvider | AzureProvider | GcpProvider | KubernetesProvider: An instance of the corresponding provider class
(`AwsProvider`, `AzureProvider`, `GcpProvider`, or `KubernetesProvider`) initialized with the
AwsProvider | AzureProvider | GcpProvider | KubernetesProvider | M365Provider: An instance of the corresponding provider class
(`AwsProvider`, `AzureProvider`, `GcpProvider`, `KubernetesProvider` or `M365Provider`) initialized with the
provider's secrets.
"""
prowler_provider = return_prowler_provider(provider)
@@ -130,10 +133,12 @@ def prowler_provider_connection_test(provider: Provider) -> Connection:
Connection: A connection object representing the result of the connection test for the specified provider.
"""
prowler_provider = return_prowler_provider(provider)
try:
prowler_provider_kwargs = provider.secret.secret
except Provider.secret.RelatedObjectDoesNotExist as secret_error:
return Connection(is_connected=False, error=secret_error)
return prowler_provider.test_connection(
**prowler_provider_kwargs, provider_id=provider.uid, raise_on_exception=False
)

View File

@@ -0,0 +1,172 @@
from drf_spectacular.utils import extend_schema_field
from rest_framework_json_api import serializers
@extend_schema_field(
{
"oneOf": [
{
"type": "object",
"title": "AWS Static Credentials",
"properties": {
"aws_access_key_id": {
"type": "string",
"description": "The AWS access key ID. Required for environments where no IAM role is being "
"assumed and direct AWS access is needed.",
},
"aws_secret_access_key": {
"type": "string",
"description": "The AWS secret access key. Must accompany 'aws_access_key_id' to authorize "
"access to AWS resources.",
},
"aws_session_token": {
"type": "string",
"description": "The session token associated with temporary credentials. Only needed for "
"session-based or temporary AWS access.",
},
},
"required": ["aws_access_key_id", "aws_secret_access_key"],
},
{
"type": "object",
"title": "AWS Assume Role",
"properties": {
"role_arn": {
"type": "string",
"description": "The Amazon Resource Name (ARN) of the role to assume. Required for AWS role "
"assumption.",
},
"external_id": {
"type": "string",
"description": "An identifier to enhance security for role assumption.",
},
"aws_access_key_id": {
"type": "string",
"description": "The AWS access key ID. Only required if the environment lacks pre-configured "
"AWS credentials.",
},
"aws_secret_access_key": {
"type": "string",
"description": "The AWS secret access key. Required if 'aws_access_key_id' is provided or if "
"no AWS credentials are pre-configured.",
},
"aws_session_token": {
"type": "string",
"description": "The session token for temporary credentials, if applicable.",
},
"session_duration": {
"type": "integer",
"minimum": 900,
"maximum": 43200,
"default": 3600,
"description": "The duration (in seconds) for the role session.",
},
"role_session_name": {
"type": "string",
"description": "An identifier for the role session, useful for tracking sessions in AWS logs. "
"The regex used to validate this parameter is a string of characters consisting of "
"upper- and lower-case alphanumeric characters with no spaces. You can also include "
"underscores or any of the following characters: =,.@-\n\n"
"Examples:\n"
"- MySession123\n"
"- User_Session-1\n"
"- Test.Session@2",
"pattern": "^[a-zA-Z0-9=,.@_-]+$",
},
},
"required": ["role_arn", "external_id"],
},
{
"type": "object",
"title": "Azure Static Credentials",
"properties": {
"client_id": {
"type": "string",
"description": "The Azure application (client) ID for authentication in Azure AD.",
},
"client_secret": {
"type": "string",
"description": "The client secret associated with the application (client) ID, providing "
"secure access.",
},
"tenant_id": {
"type": "string",
"description": "The Azure tenant ID, representing the directory where the application is "
"registered.",
},
},
"required": ["client_id", "client_secret", "tenant_id"],
},
{
"type": "object",
"title": "M365 Static Credentials",
"properties": {
"client_id": {
"type": "string",
"description": "The Azure application (client) ID for authentication in Azure AD.",
},
"client_secret": {
"type": "string",
"description": "The client secret associated with the application (client) ID, providing "
"secure access.",
},
"tenant_id": {
"type": "string",
"description": "The Azure tenant ID, representing the directory where the application is "
"registered.",
},
"user": {
"type": "email",
"description": "User microsoft email address.",
},
"encrypted_password": {
"type": "string",
"description": "User encrypted password.",
},
},
"required": [
"client_id",
"client_secret",
"tenant_id",
"user",
"encrypted_password",
],
},
{
"type": "object",
"title": "GCP Static Credentials",
"properties": {
"client_id": {
"type": "string",
"description": "The client ID from Google Cloud, used to identify the application for GCP "
"access.",
},
"client_secret": {
"type": "string",
"description": "The client secret associated with the GCP client ID, required for secure "
"access.",
},
"refresh_token": {
"type": "string",
"description": "A refresh token that allows the application to obtain new access tokens for "
"extended use.",
},
},
"required": ["client_id", "client_secret", "refresh_token"],
},
{
"type": "object",
"title": "Kubernetes Static Credentials",
"properties": {
"kubeconfig_content": {
"type": "string",
"description": "The content of the Kubernetes kubeconfig file, encoded as a string.",
}
},
"required": ["kubeconfig_content"],
},
]
}
)
class ProviderSecretField(serializers.JSONField):
pass

View File

@@ -42,6 +42,7 @@ from api.v1.serializer_utils.integrations import (
IntegrationCredentialField,
S3ConfigSerializer,
)
from api.v1.serializer_utils.providers import ProviderSecretField
# Tokens
@@ -1141,6 +1142,8 @@ class BaseWriteProviderSecretSerializer(BaseWriteSerializer):
serializer = GCPProviderSecret(data=secret)
elif provider_type == Provider.ProviderChoices.KUBERNETES.value:
serializer = KubernetesProviderSecret(data=secret)
elif provider_type == Provider.ProviderChoices.M365.value:
serializer = M365ProviderSecret(data=secret)
else:
raise serializers.ValidationError(
{"provider": f"Provider type not supported {provider_type}"}
@@ -1180,6 +1183,17 @@ class AzureProviderSecret(serializers.Serializer):
resource_name = "provider-secrets"
class M365ProviderSecret(serializers.Serializer):
client_id = serializers.CharField()
client_secret = serializers.CharField()
tenant_id = serializers.CharField()
user = serializers.EmailField()
encrypted_password = serializers.CharField()
class Meta:
resource_name = "provider-secrets"
class GCPProviderSecret(serializers.Serializer):
client_id = serializers.CharField()
client_secret = serializers.CharField()
@@ -1211,141 +1225,6 @@ class AWSRoleAssumptionProviderSecret(serializers.Serializer):
resource_name = "provider-secrets"
@extend_schema_field(
{
"oneOf": [
{
"type": "object",
"title": "AWS Static Credentials",
"properties": {
"aws_access_key_id": {
"type": "string",
"description": "The AWS access key ID. Required for environments where no IAM role is being "
"assumed and direct AWS access is needed.",
},
"aws_secret_access_key": {
"type": "string",
"description": "The AWS secret access key. Must accompany 'aws_access_key_id' to authorize "
"access to AWS resources.",
},
"aws_session_token": {
"type": "string",
"description": "The session token associated with temporary credentials. Only needed for "
"session-based or temporary AWS access.",
},
},
"required": ["aws_access_key_id", "aws_secret_access_key"],
},
{
"type": "object",
"title": "AWS Assume Role",
"properties": {
"role_arn": {
"type": "string",
"description": "The Amazon Resource Name (ARN) of the role to assume. Required for AWS role "
"assumption.",
},
"external_id": {
"type": "string",
"description": "An identifier to enhance security for role assumption.",
},
"aws_access_key_id": {
"type": "string",
"description": "The AWS access key ID. Only required if the environment lacks pre-configured "
"AWS credentials.",
},
"aws_secret_access_key": {
"type": "string",
"description": "The AWS secret access key. Required if 'aws_access_key_id' is provided or if "
"no AWS credentials are pre-configured.",
},
"aws_session_token": {
"type": "string",
"description": "The session token for temporary credentials, if applicable.",
},
"session_duration": {
"type": "integer",
"minimum": 900,
"maximum": 43200,
"default": 3600,
"description": "The duration (in seconds) for the role session.",
},
"role_session_name": {
"type": "string",
"description": "An identifier for the role session, useful for tracking sessions in AWS logs. "
"The regex used to validate this parameter is a string of characters consisting of "
"upper- and lower-case alphanumeric characters with no spaces. You can also include "
"underscores or any of the following characters: =,.@-\n\n"
"Examples:\n"
"- MySession123\n"
"- User_Session-1\n"
"- Test.Session@2",
"pattern": "^[a-zA-Z0-9=,.@_-]+$",
},
},
"required": ["role_arn", "external_id"],
},
{
"type": "object",
"title": "Azure Static Credentials",
"properties": {
"client_id": {
"type": "string",
"description": "The Azure application (client) ID for authentication in Azure AD.",
},
"client_secret": {
"type": "string",
"description": "The client secret associated with the application (client) ID, providing "
"secure access.",
},
"tenant_id": {
"type": "string",
"description": "The Azure tenant ID, representing the directory where the application is "
"registered.",
},
},
"required": ["client_id", "client_secret", "tenant_id"],
},
{
"type": "object",
"title": "GCP Static Credentials",
"properties": {
"client_id": {
"type": "string",
"description": "The client ID from Google Cloud, used to identify the application for GCP "
"access.",
},
"client_secret": {
"type": "string",
"description": "The client secret associated with the GCP client ID, required for secure "
"access.",
},
"refresh_token": {
"type": "string",
"description": "A refresh token that allows the application to obtain new access tokens for "
"extended use.",
},
},
"required": ["client_id", "client_secret", "refresh_token"],
},
{
"type": "object",
"title": "Kubernetes Static Credentials",
"properties": {
"kubeconfig_content": {
"type": "string",
"description": "The content of the Kubernetes kubeconfig file, encoded as a string.",
}
},
"required": ["kubeconfig_content"],
},
]
}
)
class ProviderSecretField(serializers.JSONField):
pass
class ProviderSecretSerializer(RLSSerializer):
"""
Serializer for the ProviderSecret model.

View File

@@ -237,8 +237,9 @@ DJANGO_OUTPUT_S3_AWS_SECRET_ACCESS_KEY = env.str(
DJANGO_OUTPUT_S3_AWS_SESSION_TOKEN = env.str("DJANGO_OUTPUT_S3_AWS_SESSION_TOKEN", "")
DJANGO_OUTPUT_S3_AWS_DEFAULT_REGION = env.str("DJANGO_OUTPUT_S3_AWS_DEFAULT_REGION", "")
DJANGO_DELETION_BATCH_SIZE = env.int("DJANGO_DELETION_BATCH_SIZE", 5000)
# HTTP Security Headers
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = "DENY"
SECURE_REFERRER_POLICY = "strict-origin-when-cross-origin"
DJANGO_DELETION_BATCH_SIZE = env.int("DJANGO_DELETION_BATCH_SIZE", 5000)

View File

@@ -399,7 +399,6 @@ mainConfig:
[
"RSA-1024",
"P-192",
"SHA-1",
]
# AWS EKS Configuration

View File

@@ -0,0 +1,24 @@
import warnings
from dashboard.common_methods import get_section_containers_format3
warnings.filterwarnings("ignore")
def get_table(data):
aux = data[
[
"REQUIREMENTS_ID",
"REQUIREMENTS_DESCRIPTION",
"REQUIREMENTS_ATTRIBUTES_SECTION",
"CHECKID",
"STATUS",
"REGION",
"ACCOUNTID",
"RESOURCEID",
]
].copy()
return get_section_containers_format3(
aux, "REQUIREMENTS_ATTRIBUTES_SECTION", "REQUIREMENTS_ID"
)

View File

@@ -175,7 +175,7 @@ Due to the complexity and differences of each provider use the rest of the provi
- [GCP](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/gcp/gcp_provider.py)
- [Azure](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/azure/azure_provider.py)
- [Kubernetes](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/kubernetes/kubernetes_provider.py)
- [Microsoft365](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/microsoft365/microsoft365_provider.py)
- [M365](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/m365/m365_provider.py)
To facilitate understanding here is a pseudocode of how the most basic provider could be with examples.

View File

@@ -237,4 +237,4 @@ It is really important to check if the current Prowler's permissions for each pr
- 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
- Microsoft365: https://docs.prowler.cloud/en/latest/getting-started/requirements/#microsoft365-authentication
- M365: https://docs.prowler.cloud/en/latest/getting-started/requirements/#m365-authentication

View File

@@ -40,8 +40,8 @@ If your IAM entity enforces MFA you can use `--mfa` and Prowler will ask you to
Prowler for Azure supports the following authentication types. To use each one you need to pass the proper flag to the execution:
- [Service principal application](https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals?tabs=browser#service-principal-object) (recommended).
- Current az cli credentials stored.
- [Service Principal Application](https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals?tabs=browser#service-principal-object) (recommended).
- Current AZ CLI credentials stored.
- Interactive browser authentication.
- [Managed identity](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/overview) authentication.
@@ -98,17 +98,34 @@ Prowler will follow the same credentials search as [Google authentication librar
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 `Viewer` role to the member associated with the credentials.
### Needed permissions
Prowler for Google Cloud needs the following permissions to be set:
- **Viewer (`roles/viewer`) IAM role**: granted at the project / folder / org level in order to scan the target projects
- **Project level settings**: you need to have at least one project with the below settings:
- Identity and Access Management (IAM) API (`iam.googleapis.com`) enabled by either using the
[Google Cloud API UI](https://console.cloud.google.com/apis/api/iam.googleapis.com/metrics) or
by using the gcloud CLI `gcloud services enable iam.googleapis.com --project <your-project-id>` command
- Service Usage Consumer (`roles/serviceusage.serviceUsageConsumer`) IAM role
- Set the quota project to be this project by either running `gcloud auth application-default set-quota-project <project-id>` or by setting an environment variable:
`export GOOGLE_CLOUD_QUOTA_PROJECT=<project-id>`
The above settings must be associated to a user or service account.
???+ note
By default, `prowler` will scan all accessible GCP Projects, use flag `--project-ids` to specify the projects to be scanned.
## Microsoft365
## Microsoft 365
Prowler for Microsoft365 currently supports the following authentication types:
Prowler for M365 currently supports the following authentication types:
- [Service principal application](https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals?tabs=browser#service-principal-object) (recommended).
- Current az cli credentials stored.
- [Service Principal Application](https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals?tabs=browser#service-principal-object).
- Service Principal Application and Microsoft User Credentials (**recommended**).
- Current AZ CLI credentials stored.
- Interactive browser authentication.
@@ -128,6 +145,35 @@ export AZURE_TENANT_ID="XXXXXXXXX"
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.
Follow the instructions in the [Create Prowler Service Principal](../tutorials/azure/create-prowler-service-principal.md) section to create a service principal.
### Service Principal and User Credentials authentication (recommended)
This authentication method follows the same approach as the service principal method but introduces two additional environment variables for user credentials: `M365_USER` and `M365_ENCRYPTED_PASSWORD`.
```console
export AZURE_CLIENT_ID="XXXXXXXXX"
export AZURE_CLIENT_SECRET="XXXXXXXXX"
export AZURE_TENANT_ID="XXXXXXXXX"
export M365_USER="your_email@example.com"
export M365_ENCRYPTED_PASSWORD="6500780061006d0070006c006500700061007300730077006f0072006400" # replace this to yours
```
These two new environment variables are required to execute the PowerShell modules needed to retrieve information from M365 services. Prowler will use service principal authentication to log into MS Graph and user credentials to authenticate to Microsoft PowerShell modules.
The `M365_USER` should be your Microsoft account email, and `M365_ENCRYPTED_PASSWORD` must be an encrypted SecureString.
To convert your password into a valid encrypted string, run the following commands in PowerShell:
```console
$securePassword = ConvertTo-SecureString "examplepassword" -AsPlainText -Force
$encryptedPassword = $securePassword | ConvertFrom-SecureString
```
If everything is done correctly, you will see the encrypted string that you need to set as the `M365_ENCRYPTED_PASSWORD` environment variable.
```console
Write-Output $encryptedPassword
6500780061006d0070006c006500700061007300730077006f0072006400
```
### Interactive Browser authentication
To use `--browser-auth` the user needs to authenticate against Azure using the default browser to start the scan, also `--tenant-id` flag is required.

View File

@@ -170,7 +170,7 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler/),
* `Python >= 3.9, <= 3.12`
* `Python pip >= 21.0.0`
* AWS, GCP, Azure, Microsoft365 and/or Kubernetes credentials
* AWS, GCP, Azure, M365 and/or Kubernetes credentials
_Commands_:
@@ -423,7 +423,7 @@ While the scan is running, start exploring the findings in these sections:
### Prowler CLI
To run Prowler, you will need to specify the provider (e.g `aws`, `gcp`, `azure`, `microsoft365` or `kubernetes`):
To run Prowler, you will need to specify the provider (e.g `aws`, `gcp`, `azure`, `m365` or `kubernetes`):
???+ note
If no provider specified, AWS will be used for backward compatibility with most of v2 options.
@@ -565,23 +565,23 @@ kubectl logs prowler-XXXXX --namespace prowler-ns
???+ note
By default, `prowler` will scan all namespaces in your active Kubernetes context. Use the flag `--context` to specify the context to be scanned and `--namespaces` to specify the namespaces to be scanned.
#### Microsoft365
#### Microsoft 365
With Microsoft365 you need to specify which auth method is going to be used:
With M365 you need to specify which auth method is going to be used:
```console
# To use service principal authentication
prowler microsoft365 --sp-env-auth
prowler m365 --sp-env-auth
# To use az cli authentication
prowler microsoft365 --az-cli-auth
prowler m365 --az-cli-auth
# To use browser authentication
prowler microsoft365 --browser-auth --tenant-id "XXXXXXXX"
prowler m365 --browser-auth --tenant-id "XXXXXXXX"
```
See more details about Microsoft365 Authentication in [Requirements](getting-started/requirements.md#microsoft365)
See more details about M365 Authentication in [Requirements](getting-started/requirements/#microsoft-365)
## Prowler v2 Documentation
For **Prowler v2 Documentation**, please check it out [here](https://github.com/prowler-cloud/prowler/blob/8818f47333a0c1c1a457453c87af0ea5b89a385f/README.md).

View File

@@ -97,14 +97,15 @@ The following list includes all the Kubernetes checks with configurable variable
| `kubelet_strong_ciphers_only` | `kubelet_strong_ciphers` | String |
## Microsoft365
## M365
### Configurable Checks
The following list includes all the Microsoft365 checks with configurable variables that can be changed in the configuration yaml file:
The following list includes all the Microsoft 365 checks with configurable variables that can be changed in the configuration yaml file:
| Check Name | Value | Type |
|---------------------------------------------------------------|--------------------------------------------------|-----------------|
| `entra_admin_users_sign_in_frequency_enabled` | `sign_in_frequency` | Integer |
| `teams_external_file_sharing_restricted` | `allowed_cloud_storage_services` | List of Strings |
## Config YAML File Structure
@@ -504,10 +505,20 @@ kubernetes:
"TLS_RSA_WITH_AES_128_GCM_SHA256",
]
# Microsoft365 Configuration
microsoft365:
# Conditional Access Policy
# policy.session_controls.sign_in_frequency.frequency in hours
sign_in_frequency: 4
# M365 Configuration
m365:
# Entra Conditional Access Policy
# m365.entra_admin_users_sign_in_frequency_enabled
sign_in_frequency: 4 # 4 hours
# Teams Settings
# m365.teams_external_file_sharing_restricted
allowed_cloud_storage_services:
[
#"allow_box",
#"allow_drop_box",
#"allow_egnyte",
#"allow_google_drive",
#"allow_share_file",
]
```

View File

@@ -4,8 +4,13 @@ Prowler will use by default your User Account credentials, you can configure it
- `gcloud init` to use a new account
- `gcloud config set account <account>` to use an existing account
- `gcloud auth application-default login`
Then, obtain your access credentials using: `gcloud auth application-default login`
This will generate Application Default Credentials (ADC) that Prowler will use automatically.
---
## Using a Service Account key file
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:
@@ -16,14 +21,60 @@ prowler gcp --credentials-file path
???+ note
`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):
## Using an access token
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)
If you already have an access token (e.g., generated with `gcloud auth print-access-token`), you can run Prowler with:
Those credentials must be associated to a user or service account with proper permissions to do all checks. To make sure, add the `Viewer` role to the member associated with the credentials.
```bash
export CLOUDSDK_AUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
prowler gcp --project-ids <project-id>
```
???+ note
If using this method, it's recommended to also set the default project explicitly:
```bash
export GOOGLE_CLOUD_PROJECT=<project-id>
```
---
## Credentials lookup order
Prowler follows the same search order 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. [`CLOUDSDK_AUTH_ACCESS_TOKEN` + optional `GOOGLE_CLOUD_PROJECT`](https://cloud.google.com/sdk/gcloud/reference/auth/print-access-token)
3. [User credentials set up by using the Google Cloud CLI](https://cloud.google.com/docs/authentication/application-default-credentials#personal)
4. [Attached service account (e.g., Cloud Run, GCE, Cloud Functions)](https://cloud.google.com/docs/authentication/application-default-credentials#attached-sa)
???+ note
The credentials must belong to a user or service account with the necessary permissions.
To ensure full access, assign the roles/viewer IAM role to the identity being used.
???+ note
Prowler will use the enabled Google Cloud APIs to get the information needed to perform the checks.
---
## Needed permissions
Prowler for Google Cloud needs the following permissions to be set:
- **Viewer (`roles/viewer`) IAM role**: granted at the project / folder / org level in order to scan the target projects
- **Project level settings**: you need to have at least one project with the below settings:
- Identity and Access Management (IAM) API (`iam.googleapis.com`) enabled by either using the
[Google Cloud API UI](https://console.cloud.google.com/apis/api/iam.googleapis.com/metrics) or
by using the gcloud CLI `gcloud services enable iam.googleapis.com --project <your-project-id>` command
- Service Usage Consumer (`roles/serviceusage.serviceUsageConsumer`) IAM role
- Set the quota project to be this project by either running `gcloud auth application-default set-quota-project <project-id>` or by setting an environment variable:
`export GOOGLE_CLOUD_QUOTA_PROJECT=<project-id>`
The above settings must be associated to a user or service account.
???+ note
Prowler will use the enabled Google Cloud APIs to get the information needed to perform the checks.

View File

@@ -1,23 +1,28 @@
# Microsoft365 authentication
# Microsoft 365 authentication
By default Prowler uses MsGraph Python SDK identity package authentication methods using the class `ClientSecretCredential`.
This allows Prowler to authenticate against microsoft365 using the following methods:
This allows Prowler to authenticate against Microsoft 365 using the following methods:
- Service principal authentication by environment variables (Enterprise Application)
- Service principal and Microsoft user credentials by environment variabled (using PowerShell requires this authentication method)
- Current CLI credentials stored
- Interactive browser authentication
To launch the tool first you need to specify which method is used through the following flags:
```console
# To use service principal (app) authentication and Microsoft user credentials (to use PowerShell)
prowler m365 --env-auth
# To use service principal authentication
prowler microsoft365 --sp-env-auth
prowler m365 --sp-env-auth
# To use cli authentication
prowler microsoft365 --az-cli-auth
prowler m365 --az-cli-auth
# To use browser authentication
prowler microsoft365 --browser-auth --tenant-id "XXXXXXXX"
prowler m365 --browser-auth --tenant-id "XXXXXXXX"
```
To use Prowler you need to set up also the permissions required to access your resources in your Microsoft365 account, to more details refer to [Requirements](../../getting-started/requirements.md)
To use Prowler you need to set up also the permissions required to access your resources in your Microsoft 365 account, to more details refer to [Requirements](../../getting-started/requirements.md#microsoft-365)

View File

@@ -66,7 +66,7 @@
"# from prowler.providers.gcp.gcp_provider import GcpProvider\n",
"# from prowler.providers.azure.azure_provider import AzureProvider\n",
"# from prowler.providers.kubernetes.kubernetes_provider import KubernetesProvider\n",
"# from prowler.providers.microsoft365.microsoft365_provider import Microsoft365Provider"
"# from prowler.providers.m365.m365_provider import M365Provider"
]
},
{

1902
poetry.lock generated

File diff suppressed because it is too large Load Diff

36
prowler/CHANGELOG.md Normal file
View File

@@ -0,0 +1,36 @@
# Prowler SDK Changelog
All notable changes to the **Prowler SDK** are documented in this file.
## [v5.6.0] (Prowler UNRELEASED)
### Added
- Add SOC2 compliance framework to Azure [(#7489)](https://github.com/prowler-cloud/prowler/pull/7489).
- Add check for unused Service Accounts in GCP [(#7419)](https://github.com/prowler-cloud/prowler/pull/7419).
- Add Powershell to Microsoft365 [(#7331)](https://github.com/prowler-cloud/prowler/pull/7331).
- Add service Defender to Microsoft365 with one check for Common Attachments filter enabled in Malware Policies [(#7425)](https://github.com/prowler-cloud/prowler/pull/7425).
- Add check for Antiphishing Policy well configured in service Defender in M365 [(#7453)](https://github.com/prowler-cloud/prowler/pull/7453).
- Add check for Notifications for Internal users enabled in Malware Policies from service Defender in M365 [(#7435)](https://github.com/prowler-cloud/prowler/pull/7435).
- Support CLOUDSDK_AUTH_ACCESS_TOKEN in GCP [(#7495)](https://github.com/prowler-cloud/prowler/pull/7495).
- Add service Exchange to Microsoft365 with one check for Organizations Mailbox Auditing enabled [(#7408)](https://github.com/prowler-cloud/prowler/pull/7408)
- Add check for Bypass Disable in every Mailbox for service Defender in M365 [(#7418)](https://github.com/prowler-cloud/prowler/pull/7418)
- Add new check `teams_email_sending_to_channel_disabled` [(#7533)](https://github.com/prowler-cloud/prowler/pull/7533)
### Fixed
- Fix package name location in pyproject.toml while replicating for prowler-cloud [(#7531)](https://github.com/prowler-cloud/prowler/pull/7531).
- Remove cache in PyPI release action [(#7532)](https://github.com/prowler-cloud/prowler/pull/7532).
- Add the correct values for logger.info inside iam service [(#7526)](https://github.com/prowler-cloud/prowler/pull/7526).
---
## [v5.5.1] (Prowler v5.5.1)
### Fixed
- Add default name to contacts in Azure Defender [(#7483)](https://github.com/prowler-cloud/prowler/pull/7483).
- Handle projects without ID in GCP [(#7496)](https://github.com/prowler-cloud/prowler/pull/7496).
- Restore packages location in PyProject [(#7510)](https://github.com/prowler-cloud/prowler/pull/7510).
---

View File

@@ -51,7 +51,7 @@ from prowler.lib.outputs.compliance.cis.cis_aws import AWSCIS
from prowler.lib.outputs.compliance.cis.cis_azure import AzureCIS
from prowler.lib.outputs.compliance.cis.cis_gcp import GCPCIS
from prowler.lib.outputs.compliance.cis.cis_kubernetes import KubernetesCIS
from prowler.lib.outputs.compliance.cis.cis_microsoft365 import Microsoft365CIS
from prowler.lib.outputs.compliance.cis.cis_m365 import M365CIS
from prowler.lib.outputs.compliance.compliance import display_compliance_table
from prowler.lib.outputs.compliance.ens.ens_aws import AWSENS
from prowler.lib.outputs.compliance.ens.ens_azure import AzureENS
@@ -85,7 +85,7 @@ from prowler.providers.common.provider import Provider
from prowler.providers.common.quick_inventory import run_provider_quick_inventory
from prowler.providers.gcp.models import GCPOutputOptions
from prowler.providers.kubernetes.models import KubernetesOutputOptions
from prowler.providers.microsoft365.models import Microsoft365OutputOptions
from prowler.providers.m365.models import M365OutputOptions
from prowler.providers.nhn.models import NHNOutputOptions
@@ -268,8 +268,8 @@ def prowler():
output_options = KubernetesOutputOptions(
args, bulk_checks_metadata, global_provider.identity
)
elif provider == "microsoft365":
output_options = Microsoft365OutputOptions(
elif provider == "m365":
output_options = M365OutputOptions(
args, bulk_checks_metadata, global_provider.identity
)
elif provider == "nhn":
@@ -666,7 +666,7 @@ def prowler():
generated_outputs["compliance"].append(generic_compliance)
generic_compliance.batch_write_data_to_file()
elif provider == "microsoft365":
elif provider == "m365":
for compliance_name in input_compliance_frameworks:
if compliance_name.startswith("cis_"):
# Generate CIS Finding Object
@@ -674,7 +674,7 @@ def prowler():
f"{output_options.output_directory}/compliance/"
f"{output_options.output_filename}_{compliance_name}.csv"
)
cis = Microsoft365CIS(
cis = M365CIS(
findings=finding_outputs,
compliance=bulk_compliance_frameworks[compliance_name],
file_path=filename,

View File

@@ -0,0 +1,623 @@
{
"Framework": "SOC2",
"Version": "",
"Provider": "Azure",
"Description": "System and Organization Controls (SOC), defined by the American Institute of Certified Public Accountants (AICPA), is the name of a set of reports that's produced during an audit. It's intended for use by service organizations (organizations that provide information systems as a service to other organizations) to issue validated reports of internal controls over those information systems to the users of those services. The reports focus on controls grouped into five categories known as Trust Service Principles.",
"Requirements": [
{
"Id": "cc_1_3",
"Name": "CC1.3 COSO Principle 3: Management establishes, with board oversight, structures, reporting lines, and appropriate authorities and responsibilities in the pursuit of objectives",
"Description": "Considers All Structures of the Entity - Management and the board of directors consider the multiple structures used (including operating units, legal entities, geographic distribution, and outsourced service providers) to support the achievement of objectives. Establishes Reporting Lines - Management designs and evaluates lines of reporting for each entity structure to enable execution of authorities and responsibilities and flow of information to manage the activities of the entity. Defines, Assigns, and Limits Authorities and Responsibilities - Management and the board of directors delegate authority, define responsibilities, and use appropriate processes and technology to assign responsibility and segregate duties as necessary at the various levels of the organization. Additional points of focus specifically related to all engagements using the trust services criteria: Addresses Specific Requirements When Defining Authorities and Responsibilities—Management and the board of directors consider requirements relevant to security, availability, processing integrity, confidentiality, and privacy when defining authorities and responsibilities. Considers Interactions With External Parties When Establishing Structures, Reporting Lines, Authorities, and Responsibilities — Management and the board of directors consider the need for the entity to interact with and monitor the activities of external parties when establishing structures, reporting lines, authorities, and responsibilities.",
"Attributes": [
{
"ItemId": "cc_1_3",
"Section": "CC1.0 - Common Criteria Related to Control Environment",
"Service": "entra",
"Type": "automated"
}
],
"Checks": [
"entra_conditional_access_policy_require_mfa_for_management_api",
"entra_global_admin_in_less_than_five_users",
"entra_non_privileged_user_has_mfa",
"entra_policy_default_users_cannot_create_security_groups",
"entra_policy_ensure_default_user_cannot_create_apps",
"entra_policy_ensure_default_user_cannot_create_tenants",
"entra_policy_guest_invite_only_for_admin_roles",
"entra_policy_guest_users_access_restrictions",
"entra_policy_restricts_user_consent_for_apps",
"entra_policy_user_consent_for_verified_apps",
"entra_privileged_user_has_mfa",
"entra_security_defaults_enabled",
"entra_trusted_named_locations_exists",
"entra_user_with_vm_access_has_mfa",
"entra_users_cannot_create_microsoft_365_groups"
]
},
{
"Id": "cc_2_1",
"Name": "CC2.1 COSO Principle 13: The entity obtains or generates and uses relevant, quality information to support the functioning of internal control",
"Description": "Identifies Information Requirements - A process is in place to identify the information required and expected to support the functioning of the other components of internal control and the achievement of the entitys objectives. Captures Internal and External Sources of Data - Information systems capture internal and external sources of data. Processes Relevant Data Into Information - Information systems process and transform relevant data into information. Maintains Quality Throughout Processing - Information systems produce information that is timely, current, accurate, complete, accessible, protected, verifiable, and retained. Information is reviewed to assess its relevance in supporting the internal control components.",
"Attributes": [
{
"ItemId": "cc_2_1",
"Section": "CC2.0 - Common Criteria Related to Communication and Information",
"Service": "monitor",
"Type": "automated"
}
],
"Checks": [
"monitor_alert_create_policy_assignment",
"monitor_alert_create_update_nsg",
"monitor_alert_create_update_public_ip_address_rule",
"monitor_alert_create_update_security_solution",
"monitor_alert_create_update_sqlserver_fr",
"monitor_alert_delete_nsg",
"monitor_alert_delete_policy_assignment",
"monitor_alert_delete_public_ip_address_rule",
"monitor_alert_delete_security_solution",
"monitor_alert_delete_sqlserver_fr"
]
},
{
"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 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 entitys objectives related to reporting, operations, and compliance.",
"Attributes": [
{
"ItemId": "cc_3_1",
"Section": "CC3.0 - Common Criteria Related to Risk Assessment",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"defender_ensure_defender_for_app_services_is_on",
"defender_ensure_defender_for_arm_is_on",
"defender_ensure_defender_for_azure_sql_databases_is_on",
"defender_ensure_defender_for_containers_is_on",
"defender_ensure_defender_for_cosmosdb_is_on",
"defender_ensure_defender_for_databases_is_on",
"defender_ensure_defender_for_dns_is_on",
"defender_ensure_defender_for_keyvault_is_on",
"defender_ensure_defender_for_os_relational_databases_is_on",
"defender_ensure_defender_for_server_is_on",
"defender_ensure_defender_for_sql_servers_is_on",
"defender_ensure_defender_for_storage_is_on",
"defender_ensure_iot_hub_defender_is_on",
"defender_ensure_mcas_is_enabled",
"defender_ensure_notify_alerts_severity_is_high",
"defender_ensure_notify_emails_to_owners",
"defender_ensure_system_updates_are_applied",
"defender_ensure_wdatp_is_enabled",
"sqlserver_microsoft_defender_enabled"
]
},
{
"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.",
"Attributes": [
{
"ItemId": "cc_3_2",
"Section": "CC3.0 - Common Criteria Related to Risk Assessment",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"defender_additional_email_configured_with_a_security_contact",
"defender_assessments_vm_endpoint_protection_installed",
"defender_auto_provisioning_log_analytics_agent_vms_on",
"defender_auto_provisioning_vulnerabilty_assessments_machines_on",
"defender_container_images_resolved_vulnerabilities",
"defender_container_images_scan_enabled",
"defender_ensure_defender_for_app_services_is_on",
"defender_ensure_defender_for_arm_is_on",
"defender_ensure_defender_for_azure_sql_databases_is_on",
"defender_ensure_defender_for_containers_is_on",
"defender_ensure_defender_for_cosmosdb_is_on",
"defender_ensure_defender_for_databases_is_on",
"defender_ensure_defender_for_dns_is_on",
"defender_ensure_defender_for_keyvault_is_on",
"defender_ensure_defender_for_os_relational_databases_is_on",
"defender_ensure_defender_for_server_is_on",
"defender_ensure_defender_for_sql_servers_is_on",
"defender_ensure_defender_for_storage_is_on",
"defender_ensure_iot_hub_defender_is_on",
"defender_ensure_mcas_is_enabled",
"defender_ensure_notify_alerts_severity_is_high",
"defender_ensure_notify_emails_to_owners",
"defender_ensure_system_updates_are_applied",
"defender_ensure_wdatp_is_enabled",
"sqlserver_microsoft_defender_enabled"
]
},
{
"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 entitys 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",
"Section": "CC3.0 - Common Criteria Related to Risk Assessment",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"aks_clusters_created_with_private_nodes",
"app_function_identity_without_admin_privileges",
"containerregistry_uses_private_link",
"cosmosdb_account_use_private_endpoints",
"entra_non_privileged_user_has_mfa",
"entra_privileged_user_has_mfa",
"entra_user_with_vm_access_has_mfa",
"keyvault_private_endpoints",
"monitor_storage_account_with_activity_logs_is_private",
"storage_ensure_private_endpoints_in_storage_accounts"
]
},
{
"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.",
"Attributes": [
{
"ItemId": "cc_4_2",
"Section": "CC4.0 - Monitoring Activities",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"defender_additional_email_configured_with_a_security_contact",
"defender_assessments_vm_endpoint_protection_installed",
"defender_auto_provisioning_log_analytics_agent_vms_on",
"defender_auto_provisioning_vulnerabilty_assessments_machines_on",
"defender_container_images_resolved_vulnerabilities",
"defender_container_images_scan_enabled",
"defender_ensure_defender_for_app_services_is_on",
"defender_ensure_defender_for_arm_is_on",
"defender_ensure_defender_for_azure_sql_databases_is_on",
"defender_ensure_defender_for_containers_is_on",
"defender_ensure_defender_for_cosmosdb_is_on",
"defender_ensure_defender_for_databases_is_on",
"defender_ensure_defender_for_dns_is_on",
"defender_ensure_defender_for_keyvault_is_on",
"defender_ensure_defender_for_os_relational_databases_is_on",
"defender_ensure_defender_for_server_is_on",
"defender_ensure_defender_for_sql_servers_is_on",
"defender_ensure_defender_for_storage_is_on",
"defender_ensure_iot_hub_defender_is_on",
"defender_ensure_mcas_is_enabled",
"defender_ensure_notify_alerts_severity_is_high",
"defender_ensure_notify_emails_to_owners",
"defender_ensure_system_updates_are_applied",
"defender_ensure_wdatp_is_enabled",
"sqlserver_microsoft_defender_enabled"
]
},
{
"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 entitys 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 managements objectives.",
"Attributes": [
{
"ItemId": "cc_5_2",
"Section": "CC5.0 - Control Activities",
"Service": "monitor",
"Type": "automated"
}
],
"Checks": [
"monitor_alert_create_policy_assignment",
"monitor_alert_create_update_nsg",
"monitor_alert_create_update_public_ip_address_rule",
"monitor_alert_create_update_security_solution",
"monitor_alert_create_update_sqlserver_fr",
"monitor_alert_delete_nsg",
"monitor_alert_delete_policy_assignment",
"monitor_alert_delete_public_ip_address_rule",
"monitor_alert_delete_security_solution",
"monitor_alert_delete_sqlserver_fr"
]
},
{
"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.",
"Attributes": [
{
"ItemId": "cc_6_1",
"Section": "CC6.0 - Logical and Physical Access",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"aks_clusters_public_access_disabled",
"app_function_not_publicly_accessible",
"containerregistry_not_publicly_accessible",
"network_public_ip_shodan",
"storage_blob_public_access_level_is_disabled"
]
},
{
"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.",
"Attributes": [
{
"ItemId": "cc_6_2",
"Section": "CC6.0 - Logical and Physical Access",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"mysql_flexible_server_minimum_tls_version_12",
"mysql_flexible_server_ssl_connection_enabled",
"postgresql_flexible_server_enforce_ssl_enabled",
"sqlserver_recommended_minimal_tls_version",
"sqlserver_tde_encrypted_with_cmk",
"sqlserver_tde_encryption_enabled",
"sqlserver_unrestricted_inbound_access",
"storage_secure_transfer_required_is_enabled"
]
},
{
"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 entitys 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 assets 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",
"Section": "CC6.0 - Logical and Physical Access",
"Service": "entra",
"Type": "automated"
}
],
"Checks": [
"entra_non_privileged_user_has_mfa",
"entra_privileged_user_has_mfa",
"entra_user_with_vm_access_has_mfa"
]
},
{
"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.",
"Attributes": [
{
"ItemId": "cc_6_6",
"Section": "CC6.0 - Logical and Physical Access",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"network_http_internet_access_restricted",
"network_rdp_internet_access_restricted",
"network_ssh_internet_access_restricted",
"network_udp_internet_access_restricted",
"mysql_flexible_server_ssl_connection_enabled",
"postgresql_flexible_server_enforce_ssl_enabled",
"app_minimum_tls_version_12",
"mysql_flexible_server_minimum_tls_version_12",
"sqlserver_recommended_minimal_tls_version",
"storage_ensure_minimum_tls_version_12"
]
},
{
"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 entitys 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.",
"Attributes": [
{
"ItemId": "cc_6_7",
"Section": "CC6.0 - Logical and Physical Access",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"app_minimum_tls_version_12",
"monitor_storage_account_with_activity_logs_cmk_encrypted",
"sqlserver_tde_encrypted_with_cmk",
"sqlserver_tde_encryption_enabled",
"storage_ensure_encryption_with_customer_managed_keys",
"storage_infrastructure_encryption_is_enabled",
"storage_secure_transfer_required_is_enabled",
"vm_ensure_attached_disks_encrypted_with_cmk",
"vm_ensure_unattached_disks_encrypted_with_cmk"
]
},
{
"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 entitys 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 entitys 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",
"Section": "CC6.0 - Logical and Physical Access",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"defender_additional_email_configured_with_a_security_contact",
"defender_assessments_vm_endpoint_protection_installed",
"defender_auto_provisioning_log_analytics_agent_vms_on",
"defender_auto_provisioning_vulnerabilty_assessments_machines_on",
"defender_container_images_resolved_vulnerabilities",
"defender_container_images_scan_enabled",
"defender_ensure_defender_for_app_services_is_on",
"defender_ensure_defender_for_arm_is_on",
"defender_ensure_defender_for_azure_sql_databases_is_on",
"defender_ensure_defender_for_containers_is_on",
"defender_ensure_defender_for_cosmosdb_is_on",
"defender_ensure_defender_for_databases_is_on",
"defender_ensure_defender_for_dns_is_on",
"defender_ensure_defender_for_keyvault_is_on",
"defender_ensure_defender_for_os_relational_databases_is_on",
"defender_ensure_defender_for_server_is_on",
"defender_ensure_defender_for_sql_servers_is_on",
"defender_ensure_defender_for_storage_is_on",
"defender_ensure_iot_hub_defender_is_on",
"defender_ensure_mcas_is_enabled",
"defender_ensure_notify_alerts_severity_is_high",
"defender_ensure_notify_emails_to_owners",
"defender_ensure_system_updates_are_applied",
"defender_ensure_wdatp_is_enabled",
"sqlserver_microsoft_defender_enabled"
]
},
{
"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.",
"Attributes": [
{
"ItemId": "cc_7_1",
"Section": "CC7.0 - System Operations",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"defender_additional_email_configured_with_a_security_contact",
"defender_assessments_vm_endpoint_protection_installed",
"defender_auto_provisioning_log_analytics_agent_vms_on",
"defender_auto_provisioning_vulnerabilty_assessments_machines_on",
"defender_container_images_resolved_vulnerabilities",
"defender_container_images_scan_enabled",
"defender_ensure_defender_for_app_services_is_on",
"defender_ensure_defender_for_arm_is_on",
"defender_ensure_defender_for_azure_sql_databases_is_on",
"defender_ensure_defender_for_containers_is_on",
"defender_ensure_defender_for_cosmosdb_is_on",
"defender_ensure_defender_for_databases_is_on",
"defender_ensure_defender_for_dns_is_on",
"defender_ensure_defender_for_keyvault_is_on",
"defender_ensure_defender_for_os_relational_databases_is_on",
"defender_ensure_defender_for_server_is_on",
"defender_ensure_defender_for_sql_servers_is_on",
"defender_ensure_defender_for_storage_is_on",
"defender_ensure_iot_hub_defender_is_on",
"defender_ensure_mcas_is_enabled",
"defender_ensure_notify_alerts_severity_is_high",
"defender_ensure_notify_emails_to_owners",
"defender_ensure_system_updates_are_applied",
"defender_ensure_wdatp_is_enabled",
"sqlserver_microsoft_defender_enabled"
]
},
{
"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.",
"Attributes": [
{
"ItemId": "cc_7_2",
"Section": "CC7.0 - System Operations",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"app_http_logs_enabled",
"defender_auto_provisioning_log_analytics_agent_vms_on",
"keyvault_logging_enabled",
"monitor_storage_account_with_activity_logs_cmk_encrypted",
"monitor_storage_account_with_activity_logs_is_private",
"mysql_flexible_server_audit_log_connection_activated",
"mysql_flexible_server_audit_log_enabled",
"network_flow_log_captured_sent",
"network_flow_log_more_than_90_days",
"postgresql_flexible_server_log_checkpoints_on",
"postgresql_flexible_server_log_connections_on",
"postgresql_flexible_server_log_disconnections_on",
"postgresql_flexible_server_log_retention_days_greater_3"
]
},
{
"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.",
"Attributes": [
{
"ItemId": "cc_7_3",
"Section": "CC7.0 - System Operations",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"app_http_logs_enabled",
"defender_auto_provisioning_log_analytics_agent_vms_on",
"keyvault_logging_enabled",
"monitor_storage_account_with_activity_logs_cmk_encrypted",
"monitor_storage_account_with_activity_logs_is_private",
"mysql_flexible_server_audit_log_connection_activated",
"mysql_flexible_server_audit_log_enabled",
"network_flow_log_captured_sent",
"network_flow_log_more_than_90_days",
"postgresql_flexible_server_log_checkpoints_on",
"postgresql_flexible_server_log_connections_on",
"postgresql_flexible_server_log_disconnections_on",
"postgresql_flexible_server_log_retention_days_greater_3",
"defender_ensure_notify_alerts_severity_is_high",
"monitor_alert_create_policy_assignment",
"monitor_alert_create_update_nsg",
"monitor_alert_create_update_public_ip_address_rule",
"monitor_alert_create_update_security_solution",
"monitor_alert_create_update_sqlserver_fr",
"monitor_alert_delete_nsg",
"monitor_alert_delete_policy_assignment",
"monitor_alert_delete_public_ip_address_rule",
"monitor_alert_delete_security_solution",
"monitor_alert_delete_sqlserver_fr"
]
},
{
"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.",
"Attributes": [
{
"ItemId": "cc_7_4",
"Section": "CC7.0 - System Operations",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"defender_ensure_notify_alerts_severity_is_high",
"monitor_alert_create_policy_assignment",
"monitor_alert_create_update_nsg",
"monitor_alert_create_update_public_ip_address_rule",
"monitor_alert_create_update_security_solution",
"monitor_alert_create_update_sqlserver_fr",
"monitor_alert_delete_nsg",
"monitor_alert_delete_policy_assignment",
"monitor_alert_delete_public_ip_address_rule",
"monitor_alert_delete_security_solution",
"monitor_alert_delete_sqlserver_fr",
"storage_ensure_soft_delete_is_enabled",
"vm_ensure_attached_disks_encrypted_with_cmk",
"vm_ensure_unattached_disks_encrypted_with_cmk"
]
},
{
"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.",
"Attributes": [
{
"ItemId": "cc_7_5",
"Section": "CC7.0 - System Operations",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"vm_ensure_attached_disks_encrypted_with_cmk",
"vm_ensure_unattached_disks_encrypted_with_cmk",
"storage_ensure_encryption_with_customer_managed_keys",
"storage_infrastructure_encryption_is_enabled"
]
},
{
"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 entitys objectives related to confidentiality. Protects Personal Information - The entity protects personal information during system design, development, testing, implementation, and change processes to meet the entitys objectives related to privacy.",
"Attributes": [
{
"ItemId": "cc_8_1",
"Section": "CC8.0 - Change Management",
"Service": "monitor",
"Type": "automated"
}
],
"Checks": [
"monitor_alert_create_policy_assignment",
"monitor_alert_create_update_nsg",
"monitor_alert_create_update_public_ip_address_rule",
"monitor_alert_create_update_security_solution",
"monitor_alert_create_update_sqlserver_fr",
"monitor_alert_delete_nsg",
"monitor_alert_delete_policy_assignment",
"monitor_alert_delete_public_ip_address_rule",
"monitor_alert_delete_security_solution",
"monitor_alert_delete_sqlserver_fr",
"monitor_diagnostic_setting_with_appropriate_categories",
"monitor_diagnostic_settings_exists",
"monitor_storage_account_with_activity_logs_cmk_encrypted"
]
},
{
"Id": "cc_a_1_1",
"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.",
"Attributes": [
{
"ItemId": "cc_a_1_1",
"Section": "CCA1.0 - Additional Criterial for Availability",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"app_http_logs_enabled",
"defender_auto_provisioning_log_analytics_agent_vms_on",
"keyvault_logging_enabled",
"monitor_storage_account_with_activity_logs_cmk_encrypted",
"monitor_storage_account_with_activity_logs_is_private",
"mysql_flexible_server_audit_log_connection_activated",
"mysql_flexible_server_audit_log_enabled",
"network_flow_log_captured_sent",
"network_flow_log_more_than_90_days",
"postgresql_flexible_server_log_checkpoints_on",
"postgresql_flexible_server_log_connections_on",
"postgresql_flexible_server_log_disconnections_on",
"postgresql_flexible_server_log_retention_days_greater_3"
]
},
{
"Id": "cc_c_1_1",
"Name": "C1.1 The entity identifies and maintains confidential information to meet the entitys 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",
"Attributes": [
{
"ItemId": "cc_c_1_1",
"Section": "CCC1.0 - Additional Criterial for Confidentiality",
"Service": "storage",
"Type": "automated"
}
],
"Checks": [
"storage_ensure_soft_delete_is_enabled"
]
},
{
"Id": "cc_c_1_2",
"Name": "C1.2 The entity disposes of confidential information to meet the entitys 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.",
"Attributes": [
{
"ItemId": "cc_c_1_2",
"Section": "CCC1.0 - Additional Criterial for Confidentiality",
"Service": "azure",
"Type": "automated"
}
],
"Checks": [
"network_flow_log_more_than_90_days",
"postgresql_flexible_server_log_retention_days_greater_3",
"sqlserver_auditing_retention_90_days",
"storage_ensure_soft_delete_is_enabled"
]
}
]
}

View File

@@ -145,6 +145,7 @@
"iam_sa_no_administrative_privileges",
"iam_sa_no_user_managed_keys",
"iam_sa_user_managed_key_rotate_90_days",
"iam_service_account_unused",
"apikeys_key_rotated_in_90_days",
"apikeys_api_restrictions_configured"
],

View File

@@ -1,7 +1,7 @@
{
"Framework": "CIS",
"Version": "4.0",
"Provider": "Microsoft365",
"Provider": "M365",
"Description": "The CIS Microsoft 365 Foundations Benchmark provides prescriptive guidance for establishing a secure configuration posture for Microsoft 365 Cloud offerings running on any OS.",
"Requirements": [
{

View File

@@ -12,7 +12,7 @@ from prowler.lib.logger import logger
timestamp = datetime.today()
timestamp_utc = datetime.now(timezone.utc).replace(tzinfo=timezone.utc)
prowler_version = "5.5.0"
prowler_version = "5.6.0"
html_logo_url = "https://github.com/prowler-cloud/prowler/"
square_logo_img = "https://prowler.com/wp-content/uploads/logo-html.png"
aws_logo = "https://user-images.githubusercontent.com/38561120/235953920-3e3fba08-0795-41dc-b480-9bea57db9f2e.png"
@@ -28,7 +28,7 @@ class Provider(str, Enum):
GCP = "gcp"
AZURE = "azure"
KUBERNETES = "kubernetes"
MICROSOFT365 = "microsoft365"
M365 = "m365"
NHN = "nhn"
@@ -126,7 +126,7 @@ def load_and_validate_config_file(provider: str, config_file_path: str) -> dict:
# and a new format with a key for each provider to include their configuration values within.
if any(
key in config_file
for key in ["aws", "gcp", "azure", "kubernetes", "microsoft365"]
for key in ["aws", "gcp", "azure", "kubernetes", "m365"]
):
config = config_file.get(provider, {})
else:

View File

@@ -327,7 +327,6 @@ aws:
[
"RSA-1024",
"P-192",
"SHA-1",
]
# AWS EKS Configuration
@@ -447,6 +446,10 @@ gcp:
# GCP Compute Configuration
# gcp.compute_public_address_shodan
shodan_api_key: null
# GCP Service Account and user-managed keys unused configuration
# gcp.iam_service_account_unused
# gcp.iam_sa_user_managed_key_unused
max_unused_account_days: 180
# Kubernetes Configuration
kubernetes:
@@ -479,8 +482,18 @@ kubernetes:
]
# Microsoft365 Configuration
microsoft365:
# Conditional Access Policy
# policy.session_controls.sign_in_frequency.frequency in hours
sign_in_frequency: 4
# M365 Configuration
m365:
# Entra Conditional Access Policy
# m365.entra_admin_users_sign_in_frequency_enabled
sign_in_frequency: 4 # 4 hours
# Teams Settings
# m365.teams_external_file_sharing_restricted
allowed_cloud_storage_services:
[
#"allow_box",
#"allow_drop_box",
#"allow_egnyte",
#"allow_google_drive",
#"allow_share_file",
]

View File

@@ -1,5 +1,5 @@
### Account, Check and/or Region can be * to apply for all the cases.
### Account == Microsoft365 Tenant and Region == Microsoft365 Location
### Account == M365 Tenant and Region == M365 Location
### 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.

View File

@@ -543,8 +543,8 @@ class Check_Report_Kubernetes(Check_Report):
@dataclass
class CheckReportMicrosoft365(Check_Report):
"""Contains the Microsoft365 Check's finding information."""
class CheckReportM365(Check_Report):
"""Contains the M365 Check's finding information."""
resource_name: str
resource_id: str
@@ -558,7 +558,7 @@ class CheckReportMicrosoft365(Check_Report):
resource_id: str,
resource_location: str = "global",
) -> None:
"""Initialize the Microsoft365 Check's finding information.
"""Initialize the M365 Check's finding information.
Args:
metadata: The metadata of the check.

View File

@@ -26,15 +26,15 @@ class ProwlerArgumentParser:
self.parser = argparse.ArgumentParser(
prog="prowler",
formatter_class=RawTextHelpFormatter,
usage="prowler [-h] [--version] {aws,azure,gcp,kubernetes,microsoft365,nhn,dashboard} ...",
usage="prowler [-h] [--version] {aws,azure,gcp,kubernetes,m365,nhn,dashboard} ...",
epilog="""
Available Cloud Providers:
{aws,azure,gcp,kubernetes,microsoft365,nhn}
{aws,azure,gcp,kubernetes,m365,nhn}
aws AWS Provider
azure Azure Provider
gcp GCP Provider
kubernetes Kubernetes Provider
microsoft365 Microsoft 365 Provider
m365 Microsoft 365 Provider
nhn NHN Provider (Unofficial)
Available components:
@@ -104,6 +104,11 @@ Detailed documentation at https://docs.prowler.com
if "-" in sys.argv[1]:
sys.argv = self.__set_default_provider__(sys.argv)
# Provider aliases mapping
# Microsoft 365
elif sys.argv[1] == "microsoft365":
sys.argv[1] = "m365"
# Parse arguments
args = self.parser.parse_args()

View File

@@ -1,10 +1,10 @@
from prowler.lib.check.compliance_models import Compliance
from prowler.lib.outputs.compliance.cis.models import Microsoft365CISModel
from prowler.lib.outputs.compliance.cis.models import M365CISModel
from prowler.lib.outputs.compliance.compliance_output import ComplianceOutput
from prowler.lib.outputs.finding import Finding
class Microsoft365CIS(ComplianceOutput):
class M365CIS(ComplianceOutput):
"""
This class represents the Azure CIS compliance output.
@@ -39,7 +39,7 @@ class Microsoft365CIS(ComplianceOutput):
for requirement in compliance.Requirements:
if requirement.Id in finding_requirements:
for attribute in requirement.Attributes:
compliance_row = Microsoft365CISModel(
compliance_row = M365CISModel(
Provider=finding.provider,
Description=compliance.Description,
TenantId=finding.account_uid,
@@ -70,7 +70,7 @@ class Microsoft365CIS(ComplianceOutput):
for requirement in compliance.Requirements:
if not requirement.Checks:
for attribute in requirement.Attributes:
compliance_row = Microsoft365CISModel(
compliance_row = M365CISModel(
Provider=compliance.Provider.lower(),
Description=compliance.Description,
TenantId=finding.account_uid,

View File

@@ -69,9 +69,9 @@ class AzureCISModel(BaseModel):
Muted: bool
class Microsoft365CISModel(BaseModel):
class M365CISModel(BaseModel):
"""
Microsoft365CISModel generates a finding's output in Microsoft365 CIS Compliance format.
M365CISModel generates a finding's output in Microsoft 365 CIS Compliance format.
"""
Provider: str

View File

@@ -245,7 +245,7 @@ class Finding(BaseModel):
)
output_data["region"] = f"namespace: {check_output.namespace}"
elif provider.type == "microsoft365":
elif provider.type == "m365":
output_data["auth_method"] = (
f"{provider.identity.identity_type}: {provider.identity.identity_id}"
)
@@ -284,7 +284,7 @@ class Finding(BaseModel):
if not output_data["resource_uid"]:
logger.error(
f"Check {check_output.check_metadata.CheckID} has no resource_id."
f"Check {check_output.check_metadata.CheckID} has no resource_uid."
)
if not output_data["resource_name"]:
logger.error(

View File

@@ -546,9 +546,9 @@ class HTML(Output):
return ""
@staticmethod
def get_microsoft365_assessment_summary(provider: Provider) -> str:
def get_m365_assessment_summary(provider: Provider) -> str:
"""
get_microsoft365_assessment_summary gets the HTML assessment summary for the provider
get_m365_assessment_summary gets the HTML assessment summary for the provider
Args:
provider (Provider): the provider object
@@ -561,11 +561,11 @@ class HTML(Output):
<div class="col-md-2">
<div class="card">
<div class="card-header">
Microsoft365 Assessment Summary
M365 Assessment Summary
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<b>Microsoft365 Tenant Domain:</b> {provider.identity.tenant_domain}
<b>M365 Tenant Domain:</b> {provider.identity.tenant_domain}
</li>
</ul>
</div>
@@ -573,14 +573,14 @@ class HTML(Output):
<div class="col-md-4">
<div class="card">
<div class="card-header">
Microsoft365 Credentials
M365 Credentials
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<b>Microsoft365 Identity Type:</b> {provider.identity.identity_type}
<b>M365 Identity Type:</b> {provider.identity.identity_type}
</li>
<li class="list-group-item">
<b>Microsoft365 Identity ID:</b> {provider.identity.identity_id}
<b>M365 Identity ID:</b> {provider.identity.identity_id}
</li>
</ul>
</div>

View File

@@ -16,7 +16,7 @@ def stdout_report(finding, color, verbose, status, fix):
details = finding.location.lower()
if finding.check_metadata.Provider == "kubernetes":
details = finding.namespace.lower()
if finding.check_metadata.Provider == "microsoft365":
if finding.check_metadata.Provider == "m365":
details = finding.location
if finding.check_metadata.Provider == "nhn":
details = finding.location

View File

@@ -40,7 +40,7 @@ def display_summary_table(
elif provider.type == "kubernetes":
entity_type = "Context"
audited_entities = provider.identity.context
elif provider.type == "microsoft365":
elif provider.type == "m365":
entity_type = "Tenant Domain"
audited_entities = provider.identity.tenant_domain
elif provider.type == "nhn":

View File

@@ -0,0 +1,240 @@
import json
import platform
import queue
import re
import subprocess
import threading
from prowler.lib.logger import logger
class PowerShellSession:
"""
Base class for managing PowerShell sessions.
This class provides the core functionality for interacting with PowerShell,
including command execution, output handling, and session management.
It serves as a foundation for more specific PowerShell implementations.
Features:
- Maintains a persistent PowerShell session
- Handles command execution and output parsing
- Provides secure input sanitization
- Manages ANSI escape sequence removal
- Supports JSON output parsing
- Implements timeout handling for long-running commands
Attributes:
END (str): Marker string used to signal the end of PowerShell command output.
process (subprocess.Popen): The underlying PowerShell subprocess with open stdin, stdout, and stderr streams.
Note:
This is an abstract base class that should be extended by specific implementations
for different PowerShell use cases.
"""
END = "<END>"
def __init__(self):
"""
Initialize a persistent PowerShell session.
Creates a subprocess running PowerShell with pipes for stdin, stdout, and stderr.
The session is configured to run in interactive mode with no exit.
Note:
This is a base implementation that should be extended by subclasses
to add specific initialization logic (e.g., credential setup).
"""
# Determine the appropriate PowerShell command based on the OS
if platform.system() == "Windows":
powershell_cmd = "powershell"
else:
powershell_cmd = "pwsh"
self.process = subprocess.Popen(
[powershell_cmd, "-NoExit", "-Command", "-"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
bufsize=1,
)
def sanitize(self, credential: str) -> str:
"""
Sanitize input to prevent command injection.
Filters the input string to allow only letters, numbers, @, periods, underscores,
plus signs, and hyphens. This is a security measure to prevent command injection
attacks through credential input.
Args:
credential (str): The string to sanitize.
Returns:
str: The sanitized string containing only allowed characters.
Example:
>>> sanitize("user@domain.com!@#$")
"user@domain.com"
"""
return re.sub(r"[^a-zA-Z0-9@._+\-]", "", credential)
def remove_ansi(self, text: str) -> str:
"""
Remove ANSI color codes and other escape sequences from PowerShell output.
PowerShell often includes ANSI escape sequences in its output for terminal
coloring and formatting. This method strips these sequences to produce clean,
parseable text that can be processed programmatically.
Args:
text (str): Raw text containing ANSI escape sequences from PowerShell output.
Returns:
str: Clean text with all ANSI escape sequences removed, suitable for parsing.
Example:
>>> remove_ansi("\x1b[32mSuccess\x1b[0m")
"Success"
"""
ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
return ansi_escape.sub("", text)
def execute(self, command: str) -> dict:
"""
Send a command to PowerShell and retrieve its output.
Executes the given command in the PowerShell session, adds an END marker,
and parses the output as JSON if possible. The command is executed
asynchronously with a timeout mechanism.
Args:
command (str): PowerShell command to execute.
Returns:
dict: JSON-parsed output if available, otherwise an empty dictionary.
Example:
>>> execute("Get-Process | ConvertTo-Json")
{"Name": "process1", "Id": 1234}
"""
self.process.stdin.write(f"{command}\n")
self.process.stdin.write(f"Write-Output '{self.END}'\n")
return self.json_parse_output(self.read_output())
def read_output(self, timeout: int = 10, default: str = "") -> str:
"""
Read output from a process with timeout functionality.
This method reads lines from process stdout until it encounters the END marker
or the stream ends. If reading takes longer than the timeout period, the method
returns a default value while allowing the reading to continue in the background.
Args:
timeout (int, optional): Maximum time in seconds to wait for output.
Defaults to 10.
default (str, optional): Value to return if timeout occurs.
Defaults to empty string.
Returns:
str: Concatenated output lines or default value if timeout occurs.
Note:
This method uses a daemon thread to read the output asynchronously,
ensuring that the main thread is not blocked.
"""
output_lines = []
result_queue = queue.Queue()
def reader_thread():
try:
while True:
line = self.remove_ansi(self.process.stdout.readline().strip())
if line == self.END:
break
output_lines.append(line)
result_queue.put("\n".join(output_lines))
except Exception as e:
result_queue.put(str(e))
thread = threading.Thread(target=reader_thread)
thread.daemon = True
thread.start()
try:
return result_queue.get(timeout=timeout)
except queue.Empty:
return default
def json_parse_output(self, output: str) -> dict:
"""
Parse command execution output to JSON format.
Searches for a JSON object in the output string and parses it.
The method looks for both object and array JSON structures.
Args:
output (str): The string output from a PowerShell command.
Returns:
dict: Parsed JSON object if found, otherwise an empty dictionary.
Raises:
JSONDecodeError: If the JSON parsing fails.
Example:
>>> json_parse_output('Some text {"key": "value"} more text')
{"key": "value"}
"""
if output == "":
return {}
json_match = re.search(r"(\[.*\]|\{.*\})", output, re.DOTALL)
if not json_match:
logger.warning(
f"Could not parse PowerShell output as JSON.\nOriginal output: {output}",
)
return {}
else:
try:
return json.loads(json_match.group(1))
except json.JSONDecodeError as error:
logger.error(
f"Error parsing PowerShell output as JSON: {str(error)}\nOriginal output: {output}",
)
return {}
def close(self) -> None:
"""
Terminate the PowerShell session.
Sends an exit command to PowerShell and terminates the subprocess.
This method should be called when the session is no longer needed
to ensure proper cleanup of resources.
Note:
It's important to call this method when done with the session
to prevent resource leaks.
"""
if self.process:
try:
# Send exit command
self.process.stdin.write("exit\n")
self.process.stdin.flush()
# Terminate the process
self.process.terminate()
# Wait for the process to finish
self.process.wait(timeout=5)
except Exception:
# If process is still running, force kill it
self.process.kill()
finally:
# Close all pipes
self.process.stdin.close()
self.process.stdout.close()
self.process.stderr.close()
self.process = None

View File

@@ -939,6 +939,7 @@
"ap-southeast-3",
"ap-southeast-4",
"ap-southeast-5",
"ap-southeast-7",
"ca-central-1",
"ca-west-1",
"eu-central-1",
@@ -952,6 +953,7 @@
"il-central-1",
"me-central-1",
"me-south-1",
"mx-central-1",
"sa-east-1",
"us-east-1",
"us-east-2",
@@ -4184,10 +4186,12 @@
"entityresolution": {
"regions": {
"aws": [
"af-south-1",
"ap-northeast-1",
"ap-northeast-2",
"ap-southeast-1",
"ap-southeast-2",
"ca-central-1",
"eu-central-1",
"eu-west-1",
"eu-west-2",
@@ -6005,6 +6009,7 @@
"ap-southeast-3",
"ap-southeast-4",
"ap-southeast-5",
"ap-southeast-7",
"ca-central-1",
"ca-west-1",
"eu-central-1",
@@ -6018,6 +6023,7 @@
"il-central-1",
"me-central-1",
"me-south-1",
"mx-central-1",
"sa-east-1",
"us-east-1",
"us-east-2",
@@ -8392,6 +8398,7 @@
"qdeveloper": {
"regions": {
"aws": [
"eu-central-1",
"us-east-1"
],
"aws-cn": [],
@@ -8853,6 +8860,8 @@
"ap-southeast-2",
"ap-southeast-3",
"ap-southeast-4",
"ap-southeast-5",
"ap-southeast-7",
"ca-central-1",
"ca-west-1",
"eu-central-1",
@@ -8866,6 +8875,7 @@
"il-central-1",
"me-central-1",
"me-south-1",
"mx-central-1",
"sa-east-1",
"us-east-1",
"us-east-2",
@@ -9302,6 +9312,7 @@
"regions": {
"aws": [
"af-south-1",
"ap-east-1",
"ap-northeast-1",
"ap-northeast-2",
"ap-northeast-3",
@@ -9320,6 +9331,7 @@
"eu-west-1",
"eu-west-2",
"eu-west-3",
"il-central-1",
"me-central-1",
"me-south-1",
"sa-east-1",
@@ -11158,6 +11170,7 @@
"il-central-1",
"me-central-1",
"me-south-1",
"mx-central-1",
"sa-east-1",
"us-east-1",
"us-east-2",

View File

@@ -14,7 +14,7 @@ class acm_certificates_with_secure_key_algorithms(Check):
report.status = "PASS"
report.status_extended = f"ACM Certificate {certificate.id} for {certificate.name} uses a secure key algorithm ({certificate.key_algorithm})."
if certificate.key_algorithm in acm_client.audit_config.get(
"insecure_key_algorithms", ["RSA-1024", "P-192", "SHA-1"]
"insecure_key_algorithms", ["RSA-1024", "P-192"]
):
report.status = "FAIL"
report.status_extended = f"ACM Certificate {certificate.id} for {certificate.name} does not use a secure key algorithm ({certificate.key_algorithm})."

View File

@@ -286,7 +286,7 @@ class IAM(AWSService):
return stored_password_policy
def _get_users(self):
logger.info("IAM - List Users...")
logger.info("IAM - Get Users...")
try:
get_users_paginator = self.client.get_paginator("list_users")
users = []
@@ -469,7 +469,7 @@ class IAM(AWSService):
)
def _list_attached_role_policies(self):
logger.info("IAM - List Attached User Policies...")
logger.info("IAM - List Attached Role Policies...")
try:
if self.roles:
for role in self.roles:
@@ -712,7 +712,7 @@ class IAM(AWSService):
return roles
def _list_entities_for_policy(self, policy_arn):
logger.info("IAM - List Entities Role For Policy...")
logger.info("IAM - List Entities For Policy...")
try:
entities = {
"Users": [],

View File

@@ -161,7 +161,7 @@ class Defender(AzureService):
{
security_contact_default.name: SecurityContacts(
resource_id=security_contact_default.id,
name=security_contact_default.name,
name=security_contact_default.get("name", "default"),
emails=security_contact_default.emails,
phone=security_contact_default.phone,
alert_notifications_minimal_severity=security_contact_default.alert_notifications.minimal_severity,

View File

@@ -211,12 +211,13 @@ class Provider(ABC):
mutelist_path=arguments.mutelist_file,
fixer_config=fixer_config,
)
elif "microsoft365" in provider_class_name.lower():
elif "m365" in provider_class_name.lower():
provider_class(
region=arguments.region,
config_path=arguments.config_file,
mutelist_path=arguments.mutelist_file,
sp_env_auth=arguments.sp_env_auth,
env_auth=arguments.env_auth,
az_cli_auth=arguments.az_cli_auth,
browser_auth=arguments.browser_auth,
tenant_id=arguments.tenant_id,

View File

@@ -396,14 +396,19 @@ class GcpProvider(Provider):
client_secrets_path = os.path.abspath(credentials_file)
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = client_secrets_path
access_token = os.getenv("CLOUDSDK_AUTH_ACCESS_TOKEN")
if access_token:
logger.info("Using access token from CLOUDSDK_AUTH_ACCESS_TOKEN")
credentials = Credentials(token=access_token, scopes=scopes)
default_project_id = os.getenv("GOOGLE_CLOUD_PROJECT", "")
return credentials, default_project_id
# Get default credentials
credentials, default_project_id = default(scopes=scopes)
# Refresh the credentials to ensure they are valid
credentials.refresh(Request())
logger.info(f"Initial credentials: {credentials}")
if service_account:
# Create the impersonated credentials
credentials = impersonated_credentials.Credentials(
@@ -411,7 +416,7 @@ class GcpProvider(Provider):
target_principal=service_account,
target_scopes=scopes,
)
logger.info(f"Impersonated credentials: {credentials}")
logger.info(f"Impersonating service account: {service_account}")
return credentials, default_project_id
except Exception as error:
@@ -628,15 +633,21 @@ class GcpProvider(Provider):
.get("labels", {})
.items()
}
project_id = asset["resource"]["data"]["projectId"]
project_number = asset["resource"]["data"]["projectNumber"]
project_id = (
asset["resource"]["data"].get("projectId")
if asset["resource"]["data"].get("projectId")
else project_number
)
project_name = (
asset["resource"]["data"].get("name")
if asset["resource"]["data"].get("name")
else project_id
)
gcp_project = GCPProject(
number=asset["resource"]["data"]["projectNumber"],
number=project_number,
id=project_id,
name=(
asset["resource"]["data"].get("name")
if asset["resource"]["data"].get("name")
else project_id
),
name=project_name,
lifecycle_state=asset["resource"]["data"].get(
"lifecycleState"
),
@@ -677,15 +688,22 @@ class GcpProvider(Provider):
labels = {
k: v for k, v in project.get("labels", {}).items()
}
project_number = project["projectNumber"]
project_id = (
project.get("projectId")
if project.get("projectId")
else project_number
)
project_name = (
project.get("name")
if project.get("name")
else project_id
)
project_id = project["projectId"]
gcp_project = GCPProject(
number=project["projectNumber"],
number=project_number,
id=project_id,
name=(
project.get("name")
if project.get("name")
else project_id
),
name=project_name,
lifecycle_state=project["lifecycleState"],
labels=labels,
)

View File

@@ -8,14 +8,14 @@
"ResourceIdTemplate": "",
"Severity": "medium",
"ResourceType": "ServiceAccountKey",
"Description": "Ensure That There Are No Dormant Service Account Keys for Each Service Account. A key is considered dormant if it has been inactive for more than 180 days.",
"Description": "Ensure That There Are No Unused Service Account Keys for Each Service Account.",
"Risk": "Anyone who has access to the keys will be able to access resources through the service account. GCP-managed keys are used by Cloud Platform services such as App Engine and Compute Engine. These keys cannot be downloaded. Google will keep the keys and automatically rotate them on an approximately weekly basis. User-managed keys are created, downloadable, and managed by users.",
"RelatedUrl": "https://cloud.google.com/iam/docs/service-account-overview#identify-unused",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-user-managed-service-account-keys.html",
"Other": "",
"Terraform": ""
},
"Recommendation": {

View File

@@ -8,6 +8,9 @@ from prowler.providers.gcp.services.monitoring.monitoring_client import (
class iam_sa_user_managed_key_unused(Check):
def execute(self) -> Check_Report_GCP:
findings = []
max_unused_days = monitoring_client.audit_config.get(
"max_unused_account_days", 180
)
keys_used = monitoring_client.sa_keys_metrics
for account in iam_client.service_accounts:
for key in account.keys:
@@ -21,10 +24,10 @@ class iam_sa_user_managed_key_unused(Check):
)
if key.name in keys_used:
report.status = "PASS"
report.status_extended = f"User-managed key {key.name} for Service Account {account.email} was used over the last 180 days."
report.status_extended = f"User-managed key {key.name} for Service Account {account.email} was used over the last {max_unused_days} days."
else:
report.status = "FAIL"
report.status_extended = f"User-managed key {key.name} for Service Account {account.email} was not used over the last 180 days."
report.status_extended = f"User-managed key {key.name} for Service Account {account.email} was not used over the last {max_unused_days} days."
findings.append(report)
return findings

View File

@@ -35,6 +35,7 @@ class IAM(GCPService):
email=account["email"],
display_name=account.get("displayName", ""),
project_id=project_id,
uniqueId=account.get("uniqueId", ""),
)
)
@@ -99,6 +100,7 @@ class ServiceAccount(BaseModel):
display_name: str
keys: list[Key] = []
project_id: str
uniqueId: str
class AccessApproval(GCPService):

View File

@@ -0,0 +1,30 @@
{
"Provider": "gcp",
"CheckID": "iam_service_account_unused",
"CheckTitle": "Ensure That There Are No Unused Service Accounts",
"CheckType": [],
"ServiceName": "iam",
"SubServiceName": "",
"ResourceIdTemplate": "",
"Severity": "medium",
"ResourceType": "ServiceAccount",
"Description": "Ensure That There Are No Unused Service Accounts.",
"Risk": "A malicious actor could make use of privilege escalation or impersonation to access an unused Service Account that is over-privileged.",
"RelatedUrl": "https://cloud.google.com/iam/docs/service-account-overview#identify-unused",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "It is recommended to disable or remove unused Service Accounts.",
"Url": "https://cloud.google.com/iam/docs/service-account-overview#identify-unused"
}
},
"Categories": [],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}

View File

@@ -0,0 +1,30 @@
from prowler.lib.check.models import Check, Check_Report_GCP
from prowler.providers.gcp.services.iam.iam_client import iam_client
from prowler.providers.gcp.services.monitoring.monitoring_client import (
monitoring_client,
)
class iam_service_account_unused(Check):
def execute(self) -> Check_Report_GCP:
findings = []
max_unused_days = monitoring_client.audit_config.get(
"max_unused_account_days", 180
)
sa_ids_used = monitoring_client.sa_api_metrics
for account in iam_client.service_accounts:
report = Check_Report_GCP(
metadata=self.metadata(),
resource=account,
resource_id=account.email,
location=iam_client.region,
)
if account.uniqueId in sa_ids_used:
report.status = "PASS"
report.status_extended = f"Service Account {account.email} was used over the last {max_unused_days} days."
else:
report.status = "FAIL"
report.status_extended = f"Service Account {account.email} was not used over the last {max_unused_days} days."
findings.append(report)
return findings

View File

@@ -12,10 +12,12 @@ class Monitoring(GCPService):
super().__init__(__class__.__name__, provider, api_version="v3")
self.alert_policies = []
self.sa_keys_metrics = set()
self.sa_api_metrics = set()
self._get_alert_policies()
self._get_sa_keys_metrics(
"iam.googleapis.com/service_account/key/authn_events_count"
)
self._get_sa_api_metrics("serviceruntime.googleapis.com/api/request_count")
def _get_alert_policies(self):
for project_id in self.project_ids:
@@ -54,6 +56,7 @@ class Monitoring(GCPService):
def _get_sa_keys_metrics(self, metric_type):
try:
max_unused_days = int(self.audit_config.get("max_unused_account_days", 180))
end_time = (
datetime.datetime.now(datetime.timezone.utc)
.replace(microsecond=0)
@@ -62,7 +65,7 @@ class Monitoring(GCPService):
start_time = (
(
datetime.datetime.now(datetime.timezone.utc)
- datetime.timedelta(days=180)
- datetime.timedelta(days=max_unused_days)
)
.replace(microsecond=0)
.isoformat()
@@ -96,6 +99,53 @@ class Monitoring(GCPService):
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def _get_sa_api_metrics(self, metric_type):
try:
max_unused_days = int(self.audit_config.get("max_unused_account_days", 180))
end_time = (
datetime.datetime.now(datetime.timezone.utc)
.replace(microsecond=0)
.isoformat()
)
start_time = (
(
datetime.datetime.now(datetime.timezone.utc)
- datetime.timedelta(days=max_unused_days)
)
.replace(microsecond=0)
.isoformat()
)
for project_id in self.project_ids:
try:
request = (
self.client.projects()
.timeSeries()
.list(
name=f"projects/{project_id}",
filter=f'metric.type = "{metric_type}"',
interval_startTime=start_time,
interval_endTime=end_time,
view="HEADERS",
)
)
response = request.execute()
for metric in response.get("timeSeries", []):
sa_id = metric["resource"]["labels"].get("credential_id")
if sa_id and "serviceaccount:" in sa_id:
self.sa_api_metrics.add(
sa_id.replace("serviceaccount:", "")
)
except Exception as error:
logger.error(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
except Exception as error:
logger.error(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
class AlertPolicy(BaseModel):
name: str

View File

@@ -1,103 +1,123 @@
from prowler.exceptions.exceptions import ProwlerException
# Exceptions codes from 5000 to 5999 are reserved for Microsoft365 exceptions
class Microsoft365BaseException(ProwlerException):
"""Base class for Microsoft365 Errors."""
# Exceptions codes from 5000 to 5999 are reserved for M365 exceptions
class M365BaseException(ProwlerException):
"""Base class for M365 Errors."""
MICROSOFT365_ERROR_CODES = {
(6000, "Microsoft365EnvironmentVariableError"): {
"message": "Microsoft365 environment variable error",
"remediation": "Check the Microsoft365 environment variables and ensure they are properly set.",
(6000, "M365EnvironmentVariableError"): {
"message": "Microsoft 365 environment variable error",
"remediation": "Check the Microsoft 365 environment variables and ensure they are properly set.",
},
(6001, "Microsoft365ArgumentTypeValidationError"): {
"message": "Microsoft365 argument type validation error",
"remediation": "Check the provided argument types specific to Microsoft365 and ensure they meet the required format.",
(6001, "M365ArgumentTypeValidationError"): {
"message": "Microsoft 365 argument type validation error",
"remediation": "Check the provided argument types specific to Microsoft 365 and ensure they meet the required format.",
},
(6002, "Microsoft365SetUpRegionConfigError"): {
"message": "Microsoft365 region configuration setup error",
"remediation": "Check the Microsoft365 region configuration and ensure it is properly set up.",
(6002, "M365SetUpRegionConfigError"): {
"message": "Microsoft 365 region configuration setup error",
"remediation": "Check the Microsoft 365 region configuration and ensure it is properly set up.",
},
(6003, "Microsoft365HTTPResponseError"): {
"message": "Error in HTTP response from Microsoft365",
(6003, "M365HTTPResponseError"): {
"message": "Error in HTTP response from Microsoft 365",
"remediation": "",
},
(6004, "Microsoft365CredentialsUnavailableError"): {
"message": "Error trying to configure Microsoft365 credentials because they are unavailable",
"remediation": "Check the dictionary and ensure it is properly set up for Microsoft365 credentials. TENANT_ID, CLIENT_ID and CLIENT_SECRET are required.",
(6004, "M365CredentialsUnavailableError"): {
"message": "Error trying to configure Microsoft 365 credentials because they are unavailable",
"remediation": "Check the dictionary and ensure it is properly set up for Microsoft 365 credentials. TENANT_ID, CLIENT_ID and CLIENT_SECRET are required.",
},
(6005, "Microsoft365GetTokenIdentityError"): {
"message": "Error trying to get token from Microsoft365 Identity",
"remediation": "Check the Microsoft365 Identity and ensure it is properly set up.",
(6005, "M365GetTokenIdentityError"): {
"message": "Error trying to get token from Microsoft 365 Identity",
"remediation": "Check the Microsoft 365 Identity and ensure it is properly set up.",
},
(6006, "Microsoft365ClientAuthenticationError"): {
(6006, "M365ClientAuthenticationError"): {
"message": "Error in client authentication",
"remediation": "Check the client authentication and ensure it is properly set up.",
},
(6007, "Microsoft365NotValidTenantIdError"): {
(6007, "M365NotValidTenantIdError"): {
"message": "The provided tenant ID is not valid",
"remediation": "Check the tenant ID and ensure it is a valid ID.",
},
(6008, "Microsoft365NotValidClientIdError"): {
(6008, "M365NotValidClientIdError"): {
"message": "The provided client ID is not valid",
"remediation": "Check the client ID and ensure it is a valid ID.",
},
(6009, "Microsoft365NotValidClientSecretError"): {
(6009, "M365NotValidClientSecretError"): {
"message": "The provided client secret is not valid",
"remediation": "Check the client secret and ensure it is a valid secret.",
},
(6010, "Microsoft365ConfigCredentialsError"): {
"message": "Error in configuration of Microsoft365 credentials",
"remediation": "Check the configuration of Microsoft365 credentials and ensure it is properly set up.",
(6010, "M365ConfigCredentialsError"): {
"message": "Error in configuration of Microsoft 365 credentials",
"remediation": "Check the configuration of Microsoft 365 credentials and ensure it is properly set up.",
},
(6011, "Microsoft365ClientIdAndClientSecretNotBelongingToTenantIdError"): {
(6011, "M365ClientIdAndClientSecretNotBelongingToTenantIdError"): {
"message": "The provided client ID and client secret do not belong to the provided tenant ID",
"remediation": "Check the client ID and client secret and ensure they belong to the provided tenant ID.",
},
(6012, "Microsoft365TenantIdAndClientSecretNotBelongingToClientIdError"): {
(6012, "M365TenantIdAndClientSecretNotBelongingToClientIdError"): {
"message": "The provided tenant ID and client secret do not belong to the provided client ID",
"remediation": "Check the tenant ID and client secret and ensure they belong to the provided client ID.",
},
(6013, "Microsoft365TenantIdAndClientIdNotBelongingToClientSecretError"): {
(6013, "M365TenantIdAndClientIdNotBelongingToClientSecretError"): {
"message": "The provided tenant ID and client ID do not belong to the provided client secret",
"remediation": "Check the tenant ID and client ID and ensure they belong to the provided client secret.",
},
(6014, "Microsoft365InvalidProviderIdError"): {
(6014, "M365InvalidProviderIdError"): {
"message": "The provided provider_id does not match with the available subscriptions",
"remediation": "Check the provider_id and ensure it is a valid subscription for the given credentials.",
},
(6015, "Microsoft365NoAuthenticationMethodError"): {
"message": "No Microsoft365 authentication method found",
"remediation": "Check that any authentication method is properly set up for Microsoft365.",
(6015, "M365NoAuthenticationMethodError"): {
"message": "No Microsoft 365 authentication method found",
"remediation": "Check that any authentication method is properly set up for Microsoft 365.",
},
(6016, "Microsoft365SetUpSessionError"): {
(6016, "M365SetUpSessionError"): {
"message": "Error setting up session",
"remediation": "Check the session setup and ensure it is properly set up.",
},
(6017, "Microsoft365DefaultAzureCredentialError"): {
(6017, "M365DefaultAzureCredentialError"): {
"message": "Error with DefaultAzureCredential",
"remediation": "Ensure DefaultAzureCredential is correctly configured.",
},
(6018, "Microsoft365InteractiveBrowserCredentialError"): {
(6018, "M365InteractiveBrowserCredentialError"): {
"message": "Error with InteractiveBrowserCredential",
"remediation": "Ensure InteractiveBrowserCredential is correctly configured.",
},
(6019, "Microsoft365BrowserAuthNoTenantIDError"): {
"message": "Microsoft365 Tenant ID (--tenant-id) is required for browser authentication mode",
"remediation": "Check the Microsoft365 Tenant ID and ensure it is properly set up.",
(6019, "M365BrowserAuthNoTenantIDError"): {
"message": "Microsoft 365 Tenant ID (--tenant-id) is required for browser authentication mode",
"remediation": "Check the Microsoft 365 Tenant ID and ensure it is properly set up.",
},
(6020, "Microsoft365BrowserAuthNoFlagError"): {
"message": "Microsoft365 tenant ID error: browser authentication flag (--browser-auth) not found",
(6020, "M365BrowserAuthNoFlagError"): {
"message": "Microsoft 365 tenant ID error: browser authentication flag (--browser-auth) not found",
"remediation": "To use browser authentication, ensure the tenant ID is properly set.",
},
(6021, "Microsoft365NotTenantIdButClientIdAndClientSecretError"): {
"message": "Tenant Id is required for Microsoft365 static credentials. Make sure you are using the correct credentials.",
"remediation": "Check the Microsoft365 Tenant ID and ensure it is properly set up.",
(6021, "M365NotTenantIdButClientIdAndClientSecretError"): {
"message": "Tenant Id is required for Microsoft 365 static credentials. Make sure you are using the correct credentials.",
"remediation": "Check the Microsoft 365 Tenant ID and ensure it is properly set up.",
},
(6022, "M365MissingEnvironmentCredentialsError"): {
"message": "User and Password environment variables are needed to use Credentials authentication method.",
"remediation": "Ensure your environment variables are properly set up.",
},
(6023, "M365EnvironmentUserCredentialsError"): {
"message": "User or Password environment variables are not correct.",
"remediation": "Ensure you are using the right credentials.",
},
(6024, "M365NotValidUserError"): {
"message": "The provided M365 User is not valid.",
"remediation": "Check the M365 User and ensure it is a valid user.",
},
(6025, "M365NotValidEncryptedPasswordError"): {
"message": "The provided M365 Encrypted Password is not valid.",
"remediation": "Check the M365 Encrypted Password and ensure it is a valid password.",
},
(6026, "M365UserNotBelongingToTenantError"): {
"message": "The provided M365 User does not belong to the specified tenant.",
"remediation": "Check the M365 User email domain and ensure it belongs to the specified tenant.",
},
}
def __init__(self, code, file=None, original_exception=None, message=None):
provider = "Microsoft365"
provider = "M365"
error_info = self.MICROSOFT365_ERROR_CODES.get((code, self.__class__.__name__))
if message:
error_info["message"] = message
@@ -110,170 +130,197 @@ class Microsoft365BaseException(ProwlerException):
)
class Microsoft365CredentialsError(Microsoft365BaseException):
"""Base class for Microsoft365 credentials errors."""
class M365CredentialsError(M365BaseException):
"""Base class for M365 credentials errors."""
def __init__(self, code, file=None, original_exception=None, message=None):
super().__init__(code, file, original_exception, message)
class Microsoft365EnvironmentVariableError(Microsoft365CredentialsError):
class M365EnvironmentVariableError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6000, file=file, original_exception=original_exception, message=message
)
class Microsoft365ArgumentTypeValidationError(Microsoft365BaseException):
class M365ArgumentTypeValidationError(M365BaseException):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6001, file=file, original_exception=original_exception, message=message
)
class Microsoft365SetUpRegionConfigError(Microsoft365BaseException):
class M365SetUpRegionConfigError(M365BaseException):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6002, file=file, original_exception=original_exception, message=message
)
class Microsoft365HTTPResponseError(Microsoft365BaseException):
class M365HTTPResponseError(M365BaseException):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6003, file=file, original_exception=original_exception, message=message
)
class Microsoft365CredentialsUnavailableError(Microsoft365CredentialsError):
class M365CredentialsUnavailableError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6004, file=file, original_exception=original_exception, message=message
)
class Microsoft365GetTokenIdentityError(Microsoft365BaseException):
class M365GetTokenIdentityError(M365BaseException):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6005, file=file, original_exception=original_exception, message=message
)
class Microsoft365ClientAuthenticationError(Microsoft365CredentialsError):
class M365ClientAuthenticationError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6006, file=file, original_exception=original_exception, message=message
)
class Microsoft365NotValidTenantIdError(Microsoft365CredentialsError):
class M365NotValidTenantIdError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6007, file=file, original_exception=original_exception, message=message
)
class Microsoft365NotValidClientIdError(Microsoft365CredentialsError):
class M365NotValidClientIdError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6008, file=file, original_exception=original_exception, message=message
)
class Microsoft365NotValidClientSecretError(Microsoft365CredentialsError):
class M365NotValidClientSecretError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6009, file=file, original_exception=original_exception, message=message
)
class Microsoft365ConfigCredentialsError(Microsoft365CredentialsError):
class M365ConfigCredentialsError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6010, file=file, original_exception=original_exception, message=message
)
class Microsoft365ClientIdAndClientSecretNotBelongingToTenantIdError(
Microsoft365CredentialsError
):
class M365ClientIdAndClientSecretNotBelongingToTenantIdError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6011, file=file, original_exception=original_exception, message=message
)
class Microsoft365TenantIdAndClientSecretNotBelongingToClientIdError(
Microsoft365CredentialsError
):
class M365TenantIdAndClientSecretNotBelongingToClientIdError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6012, file=file, original_exception=original_exception, message=message
)
class Microsoft365TenantIdAndClientIdNotBelongingToClientSecretError(
Microsoft365CredentialsError
):
class M365TenantIdAndClientIdNotBelongingToClientSecretError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6013, file=file, original_exception=original_exception, message=message
)
class Microsoft365InvalidProviderIdError(Microsoft365BaseException):
class M365InvalidProviderIdError(M365BaseException):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6014, file=file, original_exception=original_exception, message=message
)
class Microsoft365NoAuthenticationMethodError(Microsoft365CredentialsError):
class M365NoAuthenticationMethodError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6015, file=file, original_exception=original_exception, message=message
)
class Microsoft365SetUpSessionError(Microsoft365CredentialsError):
class M365SetUpSessionError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6016, file=file, original_exception=original_exception, message=message
)
class Microsoft365DefaultAzureCredentialError(Microsoft365CredentialsError):
class M365DefaultAzureCredentialError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6017, file=file, original_exception=original_exception, message=message
)
class Microsoft365InteractiveBrowserCredentialError(Microsoft365CredentialsError):
class M365InteractiveBrowserCredentialError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6018, file=file, original_exception=original_exception, message=message
)
class Microsoft365BrowserAuthNoTenantIDError(Microsoft365CredentialsError):
class M365BrowserAuthNoTenantIDError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6019, file=file, original_exception=original_exception, message=message
)
class Microsoft365BrowserAuthNoFlagError(Microsoft365CredentialsError):
class M365BrowserAuthNoFlagError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6020, file=file, original_exception=original_exception, message=message
)
class Microsoft365NotTenantIdButClientIdAndClientSecretError(
Microsoft365CredentialsError
):
class M365NotTenantIdButClientIdAndClientSecretError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6021, file=file, original_exception=original_exception, message=message
)
class M365MissingEnvironmentCredentialsError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6022, file=file, original_exception=original_exception, message=message
)
class M365EnvironmentUserCredentialsError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6023, file=file, original_exception=original_exception, message=message
)
class M365NotValidUserError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6024, file=file, original_exception=original_exception, message=message
)
class M365NotValidEncryptedPasswordError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6025, file=file, original_exception=original_exception, message=message
)
class M365UserNotBelongingToTenantError(M365CredentialsError):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
6026, file=file, original_exception=original_exception, message=message
)

View File

@@ -0,0 +1,61 @@
def init_parser(self):
"""Init the M365 Provider CLI parser"""
m365_parser = self.subparsers.add_parser(
"m365",
parents=[self.common_providers_parser],
help="M365 Provider",
)
# Authentication Modes
m365_auth_subparser = m365_parser.add_argument_group("Authentication Modes")
m365_auth_modes_group = m365_auth_subparser.add_mutually_exclusive_group()
m365_auth_modes_group.add_argument(
"--az-cli-auth",
action="store_true",
help="Use Azure CLI authentication to log in against Microsoft 365",
)
m365_auth_modes_group.add_argument(
"--env-auth",
action="store_true",
help="Use User and Password environment variables authentication to log in against Microsoft 365",
)
m365_auth_modes_group.add_argument(
"--sp-env-auth",
action="store_true",
help="Use Azure Service Principal environment variables authentication to log in against Microsoft 365",
)
m365_auth_modes_group.add_argument(
"--browser-auth",
action="store_true",
help="Use Azure interactive browser authentication to log in against Microsoft 365",
)
m365_parser.add_argument(
"--tenant-id",
nargs="?",
default=None,
help="Microsoft 365 Tenant ID to be used with --browser-auth option",
)
m365_parser.add_argument(
"--user",
nargs="?",
default=None,
help="Microsoft 365 user email",
)
m365_parser.add_argument(
"--encypted-password",
nargs="?",
default=None,
help="Microsoft 365 encrypted password",
)
# Regions
m365_regions_subparser = m365_parser.add_argument_group("Regions")
m365_regions_subparser.add_argument(
"--region",
nargs="?",
default="M365Global",
choices=[
"M365Global",
"M365GlobalChina",
"M365USGovernment",
],
help="Microsoft 365 region to be used, default is M365Global",
)

View File

@@ -1,12 +1,12 @@
from prowler.lib.check.models import CheckReportMicrosoft365
from prowler.lib.check.models import CheckReportM365
from prowler.lib.mutelist.mutelist import Mutelist
from prowler.lib.outputs.utils import unroll_dict, unroll_tags
class Microsoft365Mutelist(Mutelist):
class M365Mutelist(Mutelist):
def is_finding_muted(
self,
finding: CheckReportMicrosoft365,
finding: CheckReportM365,
) -> bool:
return self.is_muted(
finding.tenant_id,

View File

@@ -0,0 +1,289 @@
import os
import msal
from prowler.lib.powershell.powershell import PowerShellSession
from prowler.providers.m365.exceptions.exceptions import (
M365UserNotBelongingToTenantError,
)
from prowler.providers.m365.models import M365Credentials
class M365PowerShell(PowerShellSession):
"""
Microsoft 365 specific PowerShell session management implementation.
This class extends the base PowerShellSession to provide Microsoft 365 specific
functionality, including authentication, Teams management, and Exchange Online
operations.
Features:
- Microsoft 365 credential management
- Teams client configuration
- Exchange Online connectivity
- Audit log configuration
- Secure credential handling
Attributes:
credentials (M365Credentials): The Microsoft 365 credentials used for authentication.
Note:
This class requires the Microsoft Teams and Exchange Online PowerShell modules
to be installed and available in the PowerShell environment.
"""
def __init__(self, credentials: M365Credentials):
"""
Initialize a Microsoft 365 PowerShell session.
Sets up the PowerShell session and initializes the provided credentials
for Microsoft 365 authentication.
Args:
credentials (M365Credentials): The Microsoft 365 credentials to use
for authentication.
"""
super().__init__()
self.init_credential(credentials)
def init_credential(self, credentials: M365Credentials) -> None:
"""
Initialize PowerShell credential object for Microsoft 365 authentication.
Sanitizes the username and password, then creates a PSCredential object
in the PowerShell session for use with Microsoft 365 cmdlets.
Args:
credentials (M365Credentials): The credentials object containing
username and password.
Note:
The credentials are sanitized to prevent command injection and
stored securely in the PowerShell session.
"""
# Sanitize user and password
user = self.sanitize(credentials.user)
passwd = self.sanitize(credentials.passwd)
# Securely convert encrypted password to SecureString
self.execute(f'$user = "{user}"')
self.execute(f'$secureString = "{passwd}" | ConvertTo-SecureString')
self.execute(
"$credential = New-Object System.Management.Automation.PSCredential ($user, $secureString)"
)
def test_credentials(self, credentials: M365Credentials) -> bool:
"""
Test Microsoft 365 credentials by attempting to authenticate against Entra ID.
Args:
credentials (M365Credentials): The credentials object containing
username and password to test.
Returns:
bool: True if credentials are valid and authentication succeeds, False otherwise.
"""
self.execute(
f'$securePassword = "{credentials.passwd}" | ConvertTo-SecureString\n'
)
self.execute(
f'$credential = New-Object System.Management.Automation.PSCredential("{credentials.user}", $securePassword)\n'
)
self.process.stdin.write(
'Write-Output "$($credential.GetNetworkCredential().Password)"\n'
)
self.process.stdin.write(f"Write-Output '{self.END}'\n")
decrypted_password = self.read_output()
app = msal.ConfidentialClientApplication(
client_id=credentials.client_id,
client_credential=credentials.client_secret,
authority=f"https://login.microsoftonline.com/{credentials.tenant_id}",
)
result = app.acquire_token_by_username_password(
username=credentials.user,
password=decrypted_password, # Needs to be in plain text
scopes=["https://graph.microsoft.com/.default"],
)
if result is None:
return False
if "access_token" not in result:
return False
# Validate user credentials belong to tenant
user_domain = credentials.user.split("@")[1]
if not credentials.provider_id.endswith(user_domain):
raise M365UserNotBelongingToTenantError(
file=os.path.basename(__file__),
message="The provided M365 User does not belong to the specified tenant.",
)
return True
def connect_microsoft_teams(self) -> dict:
"""
Connect to Microsoft Teams Module PowerShell Module.
Establishes a connection to Microsoft Teams using the initialized credentials.
Returns:
dict: Connection status information in JSON format.
Note:
This method requires the Microsoft Teams PowerShell module to be installed.
"""
return self.execute("Connect-MicrosoftTeams -Credential $credential")
def get_teams_settings(self) -> dict:
"""
Get Teams Client Settings.
Retrieves the current Microsoft Teams client configuration settings.
Returns:
dict: Teams client configuration settings in JSON format.
Example:
>>> get_teams_settings()
{
"AllowBox": true,
"AllowDropBox": true,
"AllowGoogleDrive": true
}
"""
return self.execute("Get-CsTeamsClientConfiguration | ConvertTo-Json")
def connect_exchange_online(self) -> dict:
"""
Connect to Exchange Online PowerShell Module.
Establishes a connection to Exchange Online using the initialized credentials.
Returns:
dict: Connection status information in JSON format.
Note:
This method requires the Exchange Online PowerShell module to be installed.
"""
return self.execute("Connect-ExchangeOnline -Credential $credential")
def get_audit_log_config(self) -> dict:
"""
Get Purview Admin Audit Log Settings.
Retrieves the current audit log configuration settings for Microsoft Purview.
Returns:
dict: Audit log configuration settings in JSON format.
Example:
>>> get_audit_log_config()
{
"UnifiedAuditLogIngestionEnabled": true
}
"""
return self.execute(
"Get-AdminAuditLogConfig | Select-Object UnifiedAuditLogIngestionEnabled | ConvertTo-Json"
)
def get_malware_filter_policy(self) -> dict:
"""
Get Defender Malware Filter Policy.
Retrieves the current Defender anti-malware filter policy settings.
Returns:
dict: Malware filter policy settings in JSON format.
Example:
>>> get_malware_filter_policy()
{
"EnableFileFilter": true,
"Identity": "Default"
}
"""
return self.execute("Get-MalwareFilterPolicy | ConvertTo-Json")
def get_antiphishing_policy(self) -> dict:
"""
Get Defender Antiphishing Policy.
Retrieves the current Defender anti-phishing policy settings.
Returns:
dict: Antiphishing policy settings in JSON format.
Example:
>>> get_antiphishing_policy()
{
"EnableSpoofIntelligence": true,
"AuthenticationFailAction": "Quarantine",
"DmarcRejectAction": "Quarantine",
"DmarcQuarantineAction": "Quarantine",
"EnableFirstContactSafetyTips": true,
"EnableUnauthenticatedSender": true,
"EnableViaTag": true,
"HonorDmarcPolicy": true,
"IsDefault": false
}
"""
return self.execute("Get-AntiPhishPolicy | ConvertTo-Json")
def get_antiphishing_rules(self) -> dict:
"""
Get Defender Antiphishing Rules.
Retrieves the current Defender anti-phishing rules.
Returns:
dict: Antiphishing rules in JSON format.
Example:
>>> get_antiphishing_rules()
{
"Name": "Rule1",
"State": Enabled,
}
"""
return self.execute("Get-AntiPhishRule | ConvertTo-Json")
def get_organization_config(self) -> dict:
"""
Get Exchange Online Organization Configuration.
Retrieves the current Exchange Online organization configuration settings.
Returns:
dict: Organization configuration settings in JSON format.
Example:
>>> get_organization_config()
{
"Name": "MyOrganization",
"Guid": "12345678-1234-1234-1234-123456789012"
"AuditDisabled": false
}
"""
return self.execute("Get-OrganizationConfig | ConvertTo-Json")
def get_mailbox_audit_config(self) -> dict:
"""
Get Exchange Online Mailbox Audit Configuration.
Retrieves the current mailbox audit configuration settings for Exchange Online.
Returns:
dict: Mailbox audit configuration settings in JSON format.
Example:
>>> get_mailbox_audit_config()
{
"Name": "MyMailbox",
"Id": "12345678-1234-1234-1234-123456789012",
"AuditBypassEnabled": false
}
"""
return self.execute("Get-MailboxAuditBypassAssociation | ConvertTo-Json")

View File

@@ -8,17 +8,17 @@ MICROSOFT365_GENERIC_CLOUD = "https://graph.microsoft.com"
def get_regions_config(region):
allowed_regions = {
"Microsoft365Global": {
"M365Global": {
"authority": None,
"base_url": MICROSOFT365_GENERIC_CLOUD,
"credential_scopes": [MICROSOFT365_GENERIC_CLOUD + "/.default"],
},
"Microsoft365China": {
"M365China": {
"authority": AzureAuthorityHosts.AZURE_CHINA,
"base_url": MICROSOFT365_CHINA_CLOUD,
"credential_scopes": [MICROSOFT365_CHINA_CLOUD + "/.default"],
},
"Microsoft365USGovernment": {
"M365USGovernment": {
"authority": AzureAuthorityHosts.AZURE_GOVERNMENT,
"base_url": MICROSOFT365_US_GOV_CLOUD,
"credential_scopes": [MICROSOFT365_US_GOV_CLOUD + "/.default"],

View File

@@ -0,0 +1,17 @@
from msgraph import GraphServiceClient
from prowler.providers.m365.lib.powershell.m365_powershell import M365PowerShell
from prowler.providers.m365.m365_provider import M365Provider
class M365Service:
def __init__(
self,
provider: M365Provider,
):
self.client = GraphServiceClient(credentials=provider.session)
self.audit_config = provider.audit_config
self.fixer_config = provider.fixer_config
if provider.credentials:
self.powershell = M365PowerShell(provider.credentials)

View File

@@ -4,7 +4,7 @@ from prowler.config.config import output_file_timestamp
from prowler.providers.common.models import ProviderOutputOptions
class Microsoft365IdentityInfo(BaseModel):
class M365IdentityInfo(BaseModel):
identity_id: str = ""
identity_type: str = ""
tenant_id: str = ""
@@ -12,14 +12,23 @@ class Microsoft365IdentityInfo(BaseModel):
location: str = ""
class Microsoft365RegionConfig(BaseModel):
class M365RegionConfig(BaseModel):
name: str = ""
authority: str = None
base_url: str = ""
credential_scopes: list = []
class Microsoft365OutputOptions(ProviderOutputOptions):
class M365Credentials(BaseModel):
user: str = ""
passwd: str = ""
client_id: str = ""
client_secret: str = ""
tenant_id: str = ""
provider_id: str = ""
class M365OutputOptions(ProviderOutputOptions):
def __init__(self, arguments, bulk_checks_metadata, identity):
# First call Provider_Output_Options init
super().__init__(arguments, bulk_checks_metadata)

View File

@@ -1,6 +1,4 @@
from prowler.providers.common.provider import Provider
from prowler.providers.microsoft365.services.admincenter.admincenter_service import (
AdminCenter,
)
from prowler.providers.m365.services.admincenter.admincenter_service import AdminCenter
admincenter_client = AdminCenter(Provider.get_global_provider())

View File

@@ -1,5 +1,5 @@
{
"Provider": "microsoft365",
"Provider": "m365",
"CheckID": "admincenter_groups_not_public_visibility",
"CheckTitle": "Ensure that only organizationally managed/approved public groups exist",
"CheckType": [],

View File

@@ -1,7 +1,7 @@
from typing import List
from prowler.lib.check.models import Check, CheckReportMicrosoft365
from prowler.providers.microsoft365.services.admincenter.admincenter_client import (
from prowler.lib.check.models import Check, CheckReportM365
from prowler.providers.m365.services.admincenter.admincenter_client import (
admincenter_client,
)
@@ -16,18 +16,18 @@ class admincenter_groups_not_public_visibility(Check):
metadata: Metadata associated with the check (inherited from Check).
"""
def execute(self) -> List[CheckReportMicrosoft365]:
def execute(self) -> List[CheckReportM365]:
"""Execute the check for groups with public visibility.
This method iterates through all groups in Microsoft Admin Center and checks
if any group has 'Public' visibility. If so, the check fails for that group.
Returns:
List[CheckReportMicrosoft365]: A list containing the results of the check for each group.
List[CheckReportM365]: A list containing the results of the check for each group.
"""
findings = []
for group in admincenter_client.groups.values():
report = CheckReportMicrosoft365(
report = CheckReportM365(
metadata=self.metadata(),
resource=group,
resource_name=group.name,

View File

@@ -1,16 +1,15 @@
from asyncio import gather, get_event_loop
from typing import List, Optional
from msgraph.generated.models.o_data_errors.o_data_error import ODataError
from pydantic import BaseModel
from prowler.lib.logger import logger
from prowler.providers.microsoft365.lib.service.service import Microsoft365Service
from prowler.providers.microsoft365.microsoft365_provider import Microsoft365Provider
from prowler.providers.m365.lib.service.service import M365Service
from prowler.providers.m365.m365_provider import M365Provider
class AdminCenter(Microsoft365Service):
def __init__(self, provider: Microsoft365Provider):
class AdminCenter(M365Service):
def __init__(self, provider: M365Provider):
super().__init__(provider)
loop = get_event_loop()
@@ -31,7 +30,7 @@ class AdminCenter(Microsoft365Service):
self.domains = attributes[2]
async def _get_users(self):
logger.info("Microsoft365 - Getting users...")
logger.info("M365 - Getting users...")
users = {}
try:
users_list = await self.client.users.get()
@@ -40,20 +39,6 @@ class AdminCenter(Microsoft365Service):
license_details = await self.client.users.by_user_id(
user.id
).license_details.get()
try:
mailbox_settings = await self.client.users.by_user_id(
user.id
).mailbox_settings.get()
mailbox_settings.user_purpose
except ODataError as error:
if error.error.code == "MailboxNotEnabledForRESTAPI":
logger.warning(
f"MailboxNotEnabledForRESTAPI for user {user.id}"
)
else:
logger.error(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
users.update(
{
user.id: User(
@@ -75,7 +60,7 @@ class AdminCenter(Microsoft365Service):
return users
async def _get_directory_roles(self):
logger.info("Microsoft365 - Getting directory roles...")
logger.info("M365 - Getting directory roles...")
directory_roles_with_members = {}
try:
directory_roles_with_members.update({})
@@ -110,7 +95,7 @@ class AdminCenter(Microsoft365Service):
return directory_roles_with_members
async def _get_groups(self):
logger.info("Microsoft365 - Getting groups...")
logger.info("M365 - Getting groups...")
groups = {}
try:
groups_list = await self.client.groups.get()
@@ -133,7 +118,7 @@ class AdminCenter(Microsoft365Service):
return groups
async def _get_domains(self):
logger.info("Microsoft365 - Getting domains...")
logger.info("M365 - Getting domains...")
domains = {}
try:
domains_list = await self.client.domains.get()

View File

@@ -1,5 +1,5 @@
{
"Provider": "microsoft365",
"Provider": "m365",
"CheckID": "admincenter_settings_password_never_expire",
"CheckTitle": "Ensure the 'Password expiration policy' is set to 'Set passwords to never expire (recommended)'",
"CheckType": [],

View File

@@ -1,7 +1,7 @@
from typing import List
from prowler.lib.check.models import Check, CheckReportMicrosoft365
from prowler.providers.microsoft365.services.admincenter.admincenter_client import (
from prowler.lib.check.models import Check, CheckReportM365
from prowler.providers.m365.services.admincenter.admincenter_client import (
admincenter_client,
)
@@ -17,19 +17,19 @@ class admincenter_settings_password_never_expire(Check):
metadata: Metadata associated with the check (inherited from Check).
"""
def execute(self) -> List[CheckReportMicrosoft365]:
def execute(self) -> List[CheckReportM365]:
"""Execute the check for password never expires policy.
This method iterates over all domains and checks if the password validity period is set
to `2147483647`, indicating that passwords for users in the domain never expire.
Returns:
List[CheckReportMicrosoft365]: A list of reports indicating whether the domain's password
List[CheckReportM365]: A list of reports indicating whether the domain's password
policy is set to never expire.
"""
findings = []
for domain in admincenter_client.domains.values():
report = CheckReportMicrosoft365(
report = CheckReportM365(
self.metadata(),
resource=domain,
resource_name=domain.id,

View File

@@ -1,5 +1,5 @@
{
"Provider": "microsoft365",
"Provider": "m365",
"CheckID": "admincenter_users_admins_reduced_license_footprint",
"CheckTitle": "Ensure administrative accounts use licenses with a reduced application footprint",
"CheckType": [],

View File

@@ -1,7 +1,7 @@
from typing import List
from prowler.lib.check.models import Check, CheckReportMicrosoft365
from prowler.providers.microsoft365.services.admincenter.admincenter_client import (
from prowler.lib.check.models import Check, CheckReportM365
from prowler.providers.m365.services.admincenter.admincenter_client import (
admincenter_client,
)
@@ -17,7 +17,7 @@ class admincenter_users_admins_reduced_license_footprint(Check):
metadata: Metadata associated with the check (inherited from Check).
"""
def execute(self) -> List[CheckReportMicrosoft365]:
def execute(self) -> List[CheckReportM365]:
"""Execute the check for users with administrative roles and their licenses.
This method iterates over all users and checks if those with administrative roles
@@ -25,7 +25,7 @@ class admincenter_users_admins_reduced_license_footprint(Check):
the check passes; otherwise, it fails.
Returns:
List[CheckReportMicrosoft365]: A list containing the result of the check for each user.
List[CheckReportM365]: A list containing the result of the check for each user.
"""
findings = []
allowed_licenses = ["AAD_PREMIUM", "AAD_PREMIUM_P2"]
@@ -39,7 +39,7 @@ class admincenter_users_admins_reduced_license_footprint(Check):
)
if admin_roles:
report = CheckReportMicrosoft365(
report = CheckReportM365(
metadata=self.metadata(),
resource=user,
resource_name=user.name,

View File

@@ -1,5 +1,5 @@
{
"Provider": "microsoft365",
"Provider": "m365",
"CheckID": "admincenter_users_between_two_and_four_global_admins",
"CheckTitle": "Ensure that between two and four global admins are designated",
"CheckType": [],

View File

@@ -1,7 +1,7 @@
from typing import List
from prowler.lib.check.models import Check, CheckReportMicrosoft365
from prowler.providers.microsoft365.services.admincenter.admincenter_client import (
from prowler.lib.check.models import Check, CheckReportM365
from prowler.providers.m365.services.admincenter.admincenter_client import (
admincenter_client,
)
@@ -16,21 +16,21 @@ class admincenter_users_between_two_and_four_global_admins(Check):
metadata: Metadata associated with the check (inherited from Check).
"""
def execute(self) -> List[CheckReportMicrosoft365]:
def execute(self) -> List[CheckReportM365]:
"""Execute the check for the number of Global Administrators.
This method checks if the number of users with the 'Global Administrator' role
is between two and four. If the condition is met, the check passes; otherwise, it fails.
Returns:
List[CheckReportMicrosoft365]: A list containing the result of the check for the Global Administrators.
List[CheckReportM365]: A list containing the result of the check for the Global Administrators.
"""
findings = []
directory_roles = admincenter_client.directory_roles
global_admin_role = directory_roles.get("Global Administrator", {})
if global_admin_role:
report = CheckReportMicrosoft365(
report = CheckReportM365(
metadata=self.metadata(),
resource=global_admin_role,
resource_name=global_admin_role.name,

View File

@@ -0,0 +1,30 @@
{
"Provider": "m365",
"CheckID": "defender_antiphishing_policy_configured",
"CheckTitle": "Ensure anti-phishing policies are properly configured and active.",
"CheckType": [],
"ServiceName": "defender",
"SubServiceName": "",
"ResourceIdTemplate": "",
"Severity": "low",
"ResourceType": "Defender Anti-Phishing Policy",
"Description": "Ensure that anti-phishing policies are created and configured for specific users, groups, or domains, taking precedence over the default policy. This check verifies the existence of rules within policies and validates specific policy settings such as spoof intelligence, DMARC actions, safety tips, and unauthenticated sender actions.",
"Risk": "Without anti-phishing policies, organizations may rely solely on default settings, which might not adequately protect against phishing attacks targeted at specific users, groups, or domains. This increases the risk of successful phishing attempts and potential data breaches.",
"RelatedUrl": "https://learn.microsoft.com/en-us/microsoft-365/security/office-365-security/set-up-anti-phishing-policies?view=o365-worldwide",
"Remediation": {
"Code": {
"CLI": "$params = @{Name='<policy_name>';PhishThresholdLevel=3;EnableTargetedUserProtection=$true;EnableOrganizationDomainsProtection=$true;EnableMailboxIntelligence=$true;EnableMailboxIntelligenceProtection=$true;EnableSpoofIntelligence=$true;TargetedUserProtectionAction='Quarantine';TargetedDomainProtectionAction='Quarantine';MailboxIntelligenceProtectionAction='Quarantine';TargetedUserQuarantineTag='DefaultFullAccessWithNotificationPolicy';MailboxIntelligenceQuarantineTag='DefaultFullAccessWithNotificationPolicy';TargetedDomainQuarantineTag='DefaultFullAccessWithNotificationPolicy';EnableFirstContactSafetyTips=$true;EnableSimilarUsersSafetyTips=$true;EnableSimilarDomainsSafetyTips=$true;EnableUnusualCharactersSafetyTips=$true;HonorDmarcPolicy=$true}; New-AntiPhishPolicy @params; New-AntiPhishRule -Name $params.Name -AntiPhishPolicy $params.Name -RecipientDomainIs (Get-AcceptedDomain).Name -Priority 0",
"NativeIaC": "",
"Other": "1. Navigate to Microsoft 365 Defender https://security.microsoft.com. 2. Click to expand Email & collaboration and select Policies & rules. 3. On the Policies & rules page select Threat policies. 4. Under Policies, select Anti-phishing 5. Ensure policies have rules with the state set to 'on' and validate settings: spoof intelligence enabled, spoof intelligence action set to 'Quarantine', DMARC reject and quarantine actions, safety tips enabled, unauthenticated sender action enabled, show tag enabled, and honor DMARC policy enabled. If not, modify them to be as recommended.",
"Terraform": ""
},
"Recommendation": {
"Text": "Create and configure anti-phishing policies for specific users, groups, or domains to enhance protection against phishing attacks.",
"Url": "https://learn.microsoft.com/en-us/microsoft-365/security/office-365-security/set-up-anti-phishing-policies?view=o365-worldwide"
}
},
"Categories": [],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}

Some files were not shown because too many files have changed in this diff Show More