-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(microsoft365): add new check entra_admin_users_sign_in_frequency_enabled
#7020
base: master
Are you sure you want to change the base?
Changes from all commits
567838b
f343d7f
785b9ef
5e249b0
40696c8
2f99dc9
20a473c
524c531
d78cbaf
1ade6bd
05cd326
c7c9f0a
c332871
0a6a22c
633bf0c
de517a2
3be0ed3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"Provider": "microsoft365", | ||
"CheckID": "entra_admin_users_sign_in_frequency_enabled", | ||
"CheckTitle": "", | ||
"CheckType": [], | ||
"ServiceName": "entra", | ||
"SubServiceName": "", | ||
"ResourceIdTemplate": "", | ||
"Severity": "high", | ||
"ResourceType": "", | ||
"Description": "Ensure Sign-in frequency periodic reauthentication does not exceed 4 hours for E3 tenants, or 24 hours for E5 tenants using Privileged Identity Management.", | ||
"Risk": "Allowing persistent browser sessions and long sign-in frequencies for administrative users increases the risk of unauthorized access. Attackers could exploit session persistence to maintain access to an admin account without reauthentication, increasing the likelihood of account compromise, especially in cases of credential theft or session hijacking.", | ||
"RelatedUrl": "https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-conditional-access-session#sign-in-frequency", | ||
"Remediation": { | ||
"Code": { | ||
"CLI": "", | ||
"NativeIaC": "", | ||
"Other": "1. Navigate to Microsoft Entra admin center https://entra.microsoft.com/. 2. Click to expand Protection > Conditional Access Select Policies. 3. Click New policy. Under Users include, select users and groups and check Directory roles. At a minimum, include the directory roles listed below in this section of the document. Under Target resources, include All cloud apps and do not create any exclusions. Under Grant, select Grant Access and check Require multifactor authentication. Under Session, select Sign-in frequency, select Periodic reauthentication, and set it to 4 hours for E3 tenants. E5 tenants with PIM can be set to a maximum value of 24 hours. Check Persistent browser session, then select Never persistent in the drop-down menu. 4. Under Enable policy, set it to Report Only until the organization is ready to enable it.", | ||
"Terraform": "" | ||
}, | ||
"Recommendation": { | ||
"Text": "Enforce a sign-in frequency limit of no more than 4 hours for E3 tenants (or 24 hours for E5 with Privileged Identity Management) and set browser sessions to Never persistent. This ensures that administrative users are regularly reauthenticated, reducing the risk of prolonged unauthorized access and mitigating session hijacking threats.", | ||
"Url": "https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-session-lifetime#user-sign-in-frequency" | ||
} | ||
}, | ||
"Categories": [], | ||
"DependsOn": [], | ||
"RelatedTo": [], | ||
"Notes": "" | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,72 @@ | ||||||
from prowler.lib.check.models import Check, CheckReportMicrosoft365 | ||||||
from prowler.providers.microsoft365.services.entra.entra_client import entra_client | ||||||
from prowler.providers.microsoft365.services.entra.entra_service import ( | ||||||
AdminRoles, | ||||||
ConditionalAccessPolicyState, | ||||||
) | ||||||
|
||||||
|
||||||
class entra_admin_users_sign_in_frequency_enabled(Check): | ||||||
"""Check if Conditional Access policies enforce sign-in frequency for admin users. | ||||||
|
||||||
This check ensures that administrators have a sign-in frequency policy enabled | ||||||
and that persistent browser session settings are correctly configured. | ||||||
""" | ||||||
|
||||||
def execute(self) -> list[CheckReportMicrosoft365]: | ||||||
"""Execute the check to validate sign-in frequency enforcement for admin users. | ||||||
|
||||||
Returns: | ||||||
list[CheckReportMicrosoft365]: A list containing the results of the check. | ||||||
""" | ||||||
findings = [] | ||||||
|
||||||
report = CheckReportMicrosoft365( | ||||||
metadata=self.metadata(), | ||||||
resource=entra_client.conditional_access_policies, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
We cannot pass a dict as a resource. |
||||||
resource_name="Conditional Access Policies", | ||||||
resource_id="conditionalAccessPolicies", | ||||||
) | ||||||
report.status = "FAIL" | ||||||
report.status_extended = ( | ||||||
"No Conditional Access policy enforces sign-in frequency for admin users." | ||||||
) | ||||||
|
||||||
for policy in entra_client.conditional_access_policies.values(): | ||||||
if policy.state not in { | ||||||
ConditionalAccessPolicyState.ENABLED, | ||||||
ConditionalAccessPolicyState.ENABLED_FOR_REPORTING, | ||||||
}: | ||||||
continue | ||||||
|
||||||
if not {role.value for role in AdminRoles}.issuperset( | ||||||
policy.conditions.user_conditions.included_roles | ||||||
): | ||||||
continue | ||||||
Check warning on line 45 in prowler/providers/microsoft365/services/entra/entra_admin_users_sign_in_frequency_enabled/entra_admin_users_sign_in_frequency_enabled.py
|
||||||
|
||||||
if ( | ||||||
"All" | ||||||
not in policy.conditions.application_conditions.included_applications | ||||||
): | ||||||
continue | ||||||
Check warning on line 51 in prowler/providers/microsoft365/services/entra/entra_admin_users_sign_in_frequency_enabled/entra_admin_users_sign_in_frequency_enabled.py
|
||||||
|
||||||
if ( | ||||||
policy.session_controls.sign_in_frequency.is_enabled | ||||||
and policy.session_controls.sign_in_frequency.frequency | ||||||
and policy.session_controls.sign_in_frequency.frequency <= 4 | ||||||
and policy.session_controls.persistent_browser.is_enabled | ||||||
and policy.session_controls.persistent_browser.mode == "never" | ||||||
): | ||||||
report = CheckReportMicrosoft365( | ||||||
metadata=self.metadata(), | ||||||
resource=entra_client.conditional_access_policies, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Same here, we cannot pass the entire dictionary as a resource. |
||||||
resource_name=policy.display_name, | ||||||
resource_id=policy.id, | ||||||
) | ||||||
report.status = "PASS" | ||||||
report.status_extended = f"Conditional Access policy {policy.display_name} enforces sign-in frequency for admin users." | ||||||
break | ||||||
|
||||||
findings.append(report) | ||||||
|
||||||
return findings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are not checking the period of the sign-in frequency, only if it is enabled. Check if it is necessary to check the period, please.