azure-b2c-userflow-idp-inject
A principal with IdentityProvider.ReadWrite.All or Global Admin can inject a malicious external IdP into a B2C user flow.
match (effective permission)
{
"action": "IdentityProvider.ReadWrite.All",
"api": "MS Graph PATCH /beta/identity/b2cUserFlows/{id}/identityProviders"
}
where
principal holds 'Global Administrator' or has effective 'IdentityProvider.ReadWrite.All' permission in the B2C tenant
emit
| source type | Identity |
|---|---|
| target type | GenericPolicy |
| source | <principal> |
| target | <B2C user flow (GenericPolicy node with provider_type Microsoft.AzureActiveDirectory/b2cDirectories/userFlows)> |
| permissions | IdentityProvider.ReadWrite.All |
| conditions | iam_permission |
| state logic | ACTIVE when the principal holds Global Administrator or effective IdentityProvider.ReadWrite.All in the B2C tenant. CONDITIONAL if the permission is behind PIM activation. BLOCKED if a Conditional Access policy prevents Graph API access to the B2C tenant. |
Narrative
{principal.name} can modify B2C user flow {target.name} configuration via PATCH /beta/identity/b2cUserFlows/{id}/identityProviders (IdentityProvider.ReadWrite.All or Global Admin), allowing injection of a malicious external OIDC or SAML IdP that will be offered as a sign-in option to all consumers using this flow.
Raw rule rules/derived/azure/b2c.yaml
id: azure-b2c-userflow-idp-inject
emits: CanModifyConfiguration
description: A principal with IdentityProvider.ReadWrite.All or Global Admin can inject a malicious external
IdP into a B2C user flow.
match_effective_permission:
action: IdentityProvider.ReadWrite.All
api: MS Graph PATCH /beta/identity/b2cUserFlows/{id}/identityProviders
where:
- principal holds 'Global Administrator' or has effective 'IdentityProvider.ReadWrite.All' permission
in the B2C tenant
emit:
source_type: Identity
target_type: GenericPolicy
source: <principal>
target: <B2C user flow (GenericPolicy node with provider_type Microsoft.AzureActiveDirectory/b2cDirectories/userFlows)>
permissions:
- IdentityProvider.ReadWrite.All
conditions:
- iam_permission
state_logic: ACTIVE when the principal holds Global Administrator or effective IdentityProvider.ReadWrite.All
in the B2C tenant. CONDITIONAL if the permission is behind PIM activation. BLOCKED if a Conditional
Access policy prevents Graph API access to the B2C tenant.
confidence: 0.8
derived_from:
- B2C tenant directory role (Global Administrator or IdentityProvider.ReadWrite.All app permission)
false_positive_note: IdentityProvider.ReadWrite.All is the only required permission for PATCH /beta/identity/b2cUserFlows/{id}/identityProviders.
Do not confuse with Policy.ReadWrite.TrustFramework, which is for custom policy XML upload (PUT /beta/trustFramework/policies).
Only emit if the principal holds IdentityProvider.ReadWrite.All directly (or inherits it from a Global
Administrator directory role). The attack requires the principal to PATCH the user flow configuration
to add a new IdP; without this permission, the user flow's IdP list is read-only.
narrative: '{principal.name} can modify B2C user flow {target.name} configuration via PATCH /beta/identity/b2cUserFlows/{id}/identityProviders
(IdentityProvider.ReadWrite.All or Global Admin), allowing injection of a malicious external OIDC
or SAML IdP that will be offered as a sign-in option to all consumers using this flow.'