Detection rules › Sigma
MFA downgrade - disable MFA policies by modifying the policies
Detect when the MFA policy is turned off by setting it to "Never".
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Stealth | T1562.007 Impair Defenses: Disable or Modify Cloud Firewall |
Rule body yaml
title: MFA downgrade - disable MFA policies by modifying the policies
id: 6733ad4e-716a-11f0-9006-723487b9527c
status: experimental
description: |
Detect when the MFA policy is turned off by setting it to "Never".
author: Okta
date: 2025-07-11
modified: 2025-09-01
logsource:
product: auth0
detection:
selection:
data.type: sapi
data.description:
- Update multi-factor authentication policies
filter_1:
data.details.response.body{}: 'all-applications'
filter_2:
data.details.response.body{}: 'confidence-score'
condition: selection and (filter_1 or filter_2)
explanation: >
The query filters for modifications of MFA settings by checking if any policies are enabled either as Always
('all-applications') or Use Adaptive MFA ('confidence-score').
It returns records when the response body is empty meaning that no policies are enabled, i.e. Never.
The Splunk query below returns only the latest policy modification record.
If MFA is set to Never, this query returns one record.
If MFA is set in Always or Use Adaptive MFA, no record is returned.
The Splunk query displays the modifying IP, user, and MFA policy enabled (Always, Adaptive, or Never).
Finally, this query can be used for reporting purposes (when and what MFA policies were enabled) by commenting
the "sort", "head", and "when" clauses.
splunk: |
index=auth0 data.tenant_name="{your-tenant-name}"
data.type=sapi data.description="Update multi-factor authentication policies"
| fields data.details.response.body{}, data.details.request.ip, data.user_id
| rename data.details.response.body{} as mfa_mode
```Take only the last change of configurations that reflects the current settings```
| sort - _time
| head 1
```Check if mfa_mode contains an empty value, i.e. no policies are enabled```
| where NOT match(mfa_mode, "^(all-applications|confidence-score)$")
| eval mfa_policy = case(
mfa_mode ="all-applications", "Always",
mfa_mode ="confidence-score", "Adaptive MFA",
true(), "Never"
)
``` Print output ```
| table _time, data.details.request.ip, data.user_id, mfa_policy
comments:
- The Splunk query above shall be tuned to reflect a valid tenant name.
- A possible false positive is when MFA policies are applied through Actions.
- Limit the detection to actions conducted from not allowlisted IPs and/or particular users.
tenant_logs: |
type: "sapi" AND description: "Update multi-factor authentication policies"
prevention:
- Control tenant admins, i.e. "Admin", as this role has permissions to modify any application.
- Enforce MFA for tenant admins to reduce the risk of an adversary gaining access.
- Control Management API scopes that allow modification of MFA settings - update:mfa_policies.
- Control usage of Management API from only trusted IPs by applying Network ACL scoped to "management".
falsepositives:
- MFA can be disabled in favour of the custom MFA setup via Actions.
- Intentional legitimate disabling by administrators.
tags:
- attack.defense-evasion
- attack.t1562
- attack.t1562.007
Stages and Predicates
Stage 0: condition
selection and (filter_1 or filter_2)Stage 1: selection
selection:
data.type: sapi
data.description:
- Update multi-factor authentication policies
Stage 2: filter_1
filter_1:
data.details.response.body{}: 'all-applications'
Stage 3: filter_2
filter_2:
data.details.response.body{}: 'confidence-score'
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
data.description | eq |
|
data.details.response.body{} | eq |
|
data.type | eq |
|