Control: 5.2.2.8 Ensure 'sign-in risk' is blocked for medium and high risk
Description
Microsoft Entra ID Protection sign-in risk detects risks in real-time and offline. A risky sign-in is an indicator for a sign-in attempt that might not have been performed by the legitimate owner of a user account.
Note: While Identity Protection also provides two risk policies with limited conditions, Microsoft highly recommends setting up risk-based policies in Conditional Access as opposed to the "legacy method" for the following benefits:
- Enhanced diagnostic data
- Report-only mode integration
- Graph API support
- Use more Conditional Access attributes like sign-in frequency in the policy
Remediation
To remediate using the UI:
- Navigate to
Microsoft Entra admin centerhttps://entra.microsoft.com/. - Click to expand
Protection>Conditional AccessselectPolicies. - Create a new policy by selecting
New policy. - Set the following conditions within the policy.
- Under
UsersincludeAll users. - Under
Target resourcesincludeAll resources (formerly 'All cloud apps')and do not set any exclusions. - Under
ConditionschooseSign-in riskvalues ofHighandMediumand clickDone. - Under
GrantchooseBlock accessand clickSelect.
- Under
- Under
Enable policyset it toReport-onlyuntil the organization is ready to enable it. - Click
Create.
Note: Break-glass accounts should be excluded from all Conditional Access policies.
Usage
Run the control in your terminal:
powerpipe control run microsoft365_compliance.control.cis_v500_5_2_2_8Snapshot and share results via Turbot Pipes:
powerpipe loginpowerpipe control run microsoft365_compliance.control.cis_v500_5_2_2_8 --shareSQL
This control uses a named query:
with tenant_list as ( select distinct on (tenant_id) tenant_id, _ctx from azuread_user),conditional_access_policy as ( select tenant_id, count(*) as conditional_access_policy_count from azuread_conditional_access_policy where users -> 'includeUsers' ? 'All' and applications -> 'includeApplications' ? 'All' and built_in_controls @> '[0]'::jsonb and sign_in_risk_levels @> '["high","medium"]'::jsonb and state = 'enabled' group by tenant_id)select t.tenant_id as resource, case when conditional_access_policy_count > 0 then 'ok' else 'alarm' end as status, case when conditional_access_policy_count > 0 then t.tenant_id || ' has a conditional access policy that blocks sign-in for medium and high risk levels.' else t.tenant_id || ' does not have a conditional access policy that blocks sign-in for medium and high risk levels.' end as reason , t.tenant_id as tenant_idfrom tenant_list as t left join conditional_access_policy as p on p.tenant_id = t.tenant_id;