turbot/steampipe-mod-microsoft365-compliance

Control: 5.2.3.7 Ensure the email OTP authentication method is disabled

Description

Authentication methods support a wide variety of scenarios for signing in to Microsoft 365 resources. Some of these methods are inherently more secure than others but require more investment in time to get users enrolled and operational.

The email one-time passcode feature is a way to authenticate B2B collaboration users when they can't be authenticated through other means, such as Microsoft Entra ID, Microsoft account (MSA), or social identity providers. When a B2B guest user tries to redeem your invitation or sign in to your shared resources, they can request a temporary passcode, which is sent to their email address. Then they enter this passcode to continue signing in.

The recommended state is to Disable email OTP.

Remediation

To remediate using the UI:

  1. Navigate to Microsoft Entra admin center https://entra.microsoft.com/.
  2. Click to expand Entra ID > Authentication methods.
  3. Select Policies.
  4. Click on Email OTP.
  5. Change the Enable toggle to the off position.
  6. Click Save.

Note: If the save button remains greyed out after toggling a method off, then first turn it back on and then change the position of the Target selection (all users or select groups). Turn the method off again and save. This was observed to be a bug in the UI at the time this document was published.

To remediate using PowerShell:

  1. Connect to Graph using Connect-MgGraph -Scopes "Policy.ReadWrite.AuthenticationMethod".
  2. Run the following:
$params = @(@{ Id = "Email"; State = "disabled" })
Update-MgPolicyAuthenticationMethodPolicy -AuthenticationMethodConfigurations $params

Default Value

Email OTP : Enabled.

Usage

Run the control in your terminal:

powerpipe control run microsoft365_compliance.control.cis_v600_5_2_3_7

Snapshot and share results via Turbot Pipes:

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

SQL

This control uses a named query:

with tenant_list as (
select distinct on (tenant_id) tenant_id, _ctx
from azuread_user
),
email_otp_status as (
select
tenant_id,
cfg ->> 'state' as email_otp_state
from
azuread_authentication_method_policy,
jsonb_array_elements(authentication_method_configurations) as cfg
where
cfg ->> 'id' = 'Email'
)
select
t.tenant_id as resource,
case
when e.email_otp_state is null then 'ok'
when e.email_otp_state = 'disabled' then 'ok'
else 'alarm'
end as status,
case
when e.email_otp_state is null then t.tenant_id || ' has Email OTP authentication method not configured.'
when e.email_otp_state = 'disabled' then t.tenant_id || ' has Email OTP authentication method disabled.'
else t.tenant_id || ' has Email OTP authentication method enabled.'
end as reason
, t.tenant_id as tenant_id
from
tenant_list as t
left join email_otp_status as e on e.tenant_id = t.tenant_id;

Tags