Skip to content

"Attempt to bypass conditional access rule" (BypassCondAccessRule.yaml) triggers false positives on benign Entra AADSTS error codes (e.g., 50076, 70043) #13815

@roniegh

Description

@roniegh

Describe the bug
The analytics rule BypassCondAccessRule.yaml generates a high volume of false positive incidents because it broadly flags any sign-in where ConditionalAccessStatus == 1 or =~ "failure". Microsoft Entra ID uses the "Failure" status for routine, non-malicious Conditional Access interruptions, such as a user changing locations and being prompted for MFA (Code 50076), or a sign-in frequency check expiring a token (Code 70043/70044). Consequently, the rule triggers alerts indiscriminately for expected user behavior.

To Reproduce

  1. Enable the "Attempt to bypass conditional access rule in Microsoft Entra ID" analytics rule.
  2. Have a user in the tenant trigger a routine Conditional Access interruption (e.g., changing networks to trigger a 50076 MFA prompt, or hitting a session lifetime limit to trigger a 70043 token expiration).
  3. Observe the rule generating an incident for an "attempt to bypass," despite the user simply following standard Entra ID prompts.

Expected behavior
The rule should distinguish between actual malicious bypass attempts and expected, benign user interruptions. It should explicitly filter out known non-malicious error codes before summarizing and generating alerts.

Additional context
Similar issue where 70043 errors trigger this exact rule: https://learn.microsoft.com/en-us/answers/questions/2237126/high-volume-of-entra-id-sign-in-errors-(code-70043

Suggested Fix:
Full credit for this KQL workaround goes to Tilman Schmidt, who originally proposed this logic in the Microsoft Q&A thread linked above.

To resolve the false positives, we can add a where clause to filter out these known benign status codes (listed below) before the first summarize statement in the query.
https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes

  • 50074 - UserStrongAuthClientAuthNRequiredInterrupt - Strong authentication is required and the user did not pass the MFA challenge.
  • 50076 - UserStrongAuthClientAuthNRequired - Due to a configuration change made by the admin such as a Conditional Access policy, per-user enforcement, or because you moved to a new location, the user must use multifactor authentication to access the resource. Retry with a new authorize request for the resource.
  • 50097 - DeviceAuthenticationRequired - Device authentication is required.
  • 50125 - PasswordResetRegistrationRequiredInterrupt - Sign-in was interrupted because of a password reset or password registration entry.
  • 50140 - KmsiInterrupt - This error occurred due to "Keep me signed in" interrupt when the user was signing-in. This is an expected part of the sign in flow, where a user is asked if they want to remain signed into their current browser to make further logins easier.
  • 70043 - BadTokenDueToSignInFrequency - The refresh token has expired or is invalid due to sign-in frequency checks by Conditional Access. The token was issued on {issueDate} and the maximum allowed lifetime for this request is {time}.
  • 700082 - ExpiredOrRevokedGrantInactiveToken - The refresh token has expired due to inactivity. The token was issued on {issueDate} and was inactive for {time}. Expected part of the token lifecycle - the user went an extended period of time without using the application, so the token was expired when the app attempted to refresh it.
| extend StatusCode = tostring(Status.errorCode), StatusDetails = tostring(Status.additionalDetails)
// ignore expected non-failure status codes
| where StatusCode !in ("50074", "50076", "50097", "50125", "50140", "70043", "700082")
| extend Status = strcat(StatusCode, ": ", ResultDescription)

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions