From b78f53a72232342d47cd72b363fcfbf20c9541ae Mon Sep 17 00:00:00 2001 From: Hugo Pereira Brito <101209179+HugoPBrito@users.noreply.github.com> Date: Mon, 12 May 2025 14:46:32 +0200 Subject: [PATCH] chore(findings): enhance m365 authentication method information (#7681) --- prowler/CHANGELOG.md | 1 + prowler/lib/outputs/html/html.py | 3 ++ prowler/providers/m365/m365_provider.py | 6 ++++ prowler/providers/m365/models.py | 1 + tests/lib/outputs/html/html_test.py | 43 +++++++++++++++++++++++++ tests/providers/m365/m365_fixtures.py | 1 + 6 files changed, 55 insertions(+) diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index 3909b08498..95d593eae7 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -64,6 +64,7 @@ All notable changes to the **Prowler SDK** are documented in this file. - Add snapshots to m365 documentation. [(#7673)](https://github.com/prowler-cloud/prowler/pull/7673) - Add support for static credentials for sending findings to Amazon S3 and AWS Security Hub. [(#7322)](https://github.com/prowler-cloud/prowler/pull/7322) - Add Prowler ThreatScore for M365 provider. [(#7692)](https://github.com/prowler-cloud/prowler/pull/7692) +- Add Microsoft User and User Credential auth to reports [(#7681)](https://github.com/prowler-cloud/prowler/pull/7681) ### Fixed diff --git a/prowler/lib/outputs/html/html.py b/prowler/lib/outputs/html/html.py index aeb11aebfc..cb462396e6 100644 --- a/prowler/lib/outputs/html/html.py +++ b/prowler/lib/outputs/html/html.py @@ -581,6 +581,9 @@ class HTML(Output):
  • M365 Identity ID: {provider.identity.identity_id}
  • + {f'''
  • + M365 User: {provider.identity.user} +
  • ''' if hasattr(provider.identity, 'user') and provider.identity.user is not None else ""} """ diff --git a/prowler/providers/m365/m365_provider.py b/prowler/providers/m365/m365_provider.py index f5011c9c27..2b766171e6 100644 --- a/prowler/providers/m365/m365_provider.py +++ b/prowler/providers/m365/m365_provider.py @@ -207,6 +207,7 @@ class M365Provider(Provider): m365_credentials=m365_credentials, provider_id=self.identity.tenant_domain, init_modules=init_modules, + identity=self.identity, ) # Audit Config @@ -382,6 +383,7 @@ class M365Provider(Provider): m365_credentials: dict = {}, provider_id: str = None, init_modules: bool = False, + identity: M365IdentityInfo = None, ) -> M365Credentials: """Gets the M365 credentials. @@ -394,6 +396,7 @@ class M365Provider(Provider): If False, returns empty credentials. """ credentials = None + if m365_credentials: credentials = M365Credentials( user=m365_credentials.get("user", ""), @@ -428,6 +431,9 @@ class M365Provider(Provider): ) if credentials: + if identity: + identity.identity_type = "Service Principal and User Credentials" + identity.user = credentials.user test_session = M365PowerShell(credentials) try: if test_session.test_credentials(credentials): diff --git a/prowler/providers/m365/models.py b/prowler/providers/m365/models.py index a2e3b68151..198c54e33e 100644 --- a/prowler/providers/m365/models.py +++ b/prowler/providers/m365/models.py @@ -10,6 +10,7 @@ class M365IdentityInfo(BaseModel): tenant_id: str = "" tenant_domain: str = "Unknown tenant domain (missing AAD permissions)" location: str = "" + user: str = None class M365RegionConfig(BaseModel): diff --git a/tests/lib/outputs/html/html_test.py b/tests/lib/outputs/html/html_test.py index 2bc6d9ab07..9ee634dc0f 100644 --- a/tests/lib/outputs/html/html_test.py +++ b/tests/lib/outputs/html/html_test.py @@ -12,6 +12,7 @@ from tests.providers.gcp.gcp_fixtures import GCP_PROJECT_ID, set_mocked_gcp_prov from tests.providers.kubernetes.kubernetes_fixtures import ( set_mocked_kubernetes_provider, ) +from tests.providers.m365.m365_fixtures import set_mocked_m365_provider html_stats = { "total_pass": 25, @@ -222,6 +223,38 @@ kubernetes_html_assessment_summary = """ """ +m365_html_assessment_summary = """ +
    +
    +
    + M365 Assessment Summary +
    + +
    +
    +
    +
    +
    + M365 Credentials +
    + +
    +
    """ + def get_aws_html_header(args: list) -> str: """ @@ -554,3 +587,13 @@ class TestHTML: summary = output.get_assessment_summary(provider) assert summary == kubernetes_html_assessment_summary + + def test_m365_get_assessment_summary(self): + findings = [generate_finding_output()] + output = HTML(findings) + provider = set_mocked_m365_provider() + + summary = output.get_assessment_summary(provider) + + expected_summary = m365_html_assessment_summary + assert summary == expected_summary diff --git a/tests/providers/m365/m365_fixtures.py b/tests/providers/m365/m365_fixtures.py index 0eb3c203e1..f985f94b6a 100644 --- a/tests/providers/m365/m365_fixtures.py +++ b/tests/providers/m365/m365_fixtures.py @@ -29,6 +29,7 @@ def set_mocked_m365_provider( identity_type=IDENTITY_TYPE, tenant_id=TENANT_ID, tenant_domain=DOMAIN, + user="user@email.com", ), audit_config: dict = None, azure_region_config: M365RegionConfig = M365RegionConfig(),