turbot/steampipe-mod-microsoft365-compliance

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:

  1. Navigate to Microsoft Entra admin center https://entra.microsoft.com/.
  2. Click to expand Protection > Conditional Access select Policies.
  3. Create a new policy by selecting New policy.
  4. Set the following conditions within the policy.
    • Under Users include All users.
    • Under Target resources include All resources (formerly 'All cloud apps') and do not set any exclusions.
    • Under Conditions choose Sign-in risk values of High and Medium and click Done.
    • Under Grant choose Block access and click Select.
  5. Under Enable policy set it to Report-only until the organization is ready to enable it.
  6. 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_8

Snapshot and share results via Turbot Pipes:

powerpipe login
powerpipe control run microsoft365_compliance.control.cis_v500_5_2_2_8 --share

SQL

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_id
from
tenant_list as t
left join conditional_access_policy as p on p.tenant_id = t.tenant_id;

Tags