azure-b2c-keyset-admin-replace-signing-key
The B2C IEF Keyset Administrator can replace the signing keyset used by custom policies, enabling token forgery for all relying party applications.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?keyset) ==
SigningKey
?keyset.provider_type == 'Microsoft.AzureActiveDirectory/b2cDirectories/trustFramework/keysets'
?keyset.use == 'sig' # signing keyset, not encryption
node_type(?policy) == TrustPolicy
principal holds B2C IEF Keyset Administrator or Global Administrator in the B2C tenant
emit
| source type | Identity |
|---|---|
| target type | TrustPolicy |
| source | ?principal |
| target | ?policy |
| permissions | microsoft.directory/b2cTrustFrameworkKeySet/allProperties/allTasks Policy.ReadWrite.TrustFramework |
| conditions | iam_permission key_permission |
| state logic | CONDITIONAL(key_permission) when the principal has confirmed B2C IEF Keyset Administrator or Global Administrator directory role in the B2C tenant. Upgrade to ACTIVE if the uploadSecret API path (POST /beta/trustFramework/keysets/{id}/uploadSecret) with attacker-supplied PEM is confirmed available. Downgrade to POTENTIAL(key_permission) if only the generateKey API (/beta/trustFramework/keysets/{id}/generateKey) is available — the attacker adds a key but cannot use it offline. CONDITIONAL if the role requires PIM activation. BLOCKED if a Conditional Access policy prevents the principal from authenticating to the B2C tenant's MS Graph endpoint. |
Narrative
{principal.name} holds the B2C IEF Keyset Administrator (or Global Admin) role and can replace the signing keyset {keyset.name} used by B2C custom policies via POST /beta/trustFramework/keysets/{id}/uploadSecret (Policy.ReadWrite.TrustFramework). Replacing the signing key with an attacker-controlled key allows forging tokens accepted by all relying party applications that validate tokens against this B2C tenant.
Raw rule rules/derived/azure/b2c.yaml
id: azure-b2c-keyset-admin-replace-signing-key
emits: CanModifyTrust
description: The B2C IEF Keyset Administrator can replace the signing keyset used by custom policies,
enabling token forgery for all relying party applications.
match:
- - principal: null
- CanAdminister
- keyset: null
- - policy: null
- HasPolicy
- keyset: null
where:
- node_type(?keyset) == SigningKey
- ?keyset.provider_type == 'Microsoft.AzureActiveDirectory/b2cDirectories/trustFramework/keysets'
- '?keyset.use == ''sig'' # signing keyset, not encryption'
- node_type(?policy) == TrustPolicy
- principal holds B2C IEF Keyset Administrator or Global Administrator in the B2C tenant
emit:
source_type: Identity
target_type: TrustPolicy
source: ?principal
target: ?policy
permissions:
- microsoft.directory/b2cTrustFrameworkKeySet/allProperties/allTasks
- Policy.ReadWrite.TrustFramework
conditions:
- iam_permission
- key_permission
state_logic: "CONDITIONAL(key_permission) when the principal has confirmed B2C IEF Keyset Administrator\
\ or Global Administrator directory role in the B2C tenant. Upgrade to ACTIVE if the uploadSecret\
\ API path (POST /beta/trustFramework/keysets/{id}/uploadSecret) with attacker-supplied PEM is confirmed\
\ available. Downgrade to POTENTIAL(key_permission) if only the generateKey API (/beta/trustFramework/keysets/{id}/generateKey)\
\ is available \u2014 the attacker adds a key but cannot use it offline. CONDITIONAL if the role requires\
\ PIM activation. BLOCKED if a Conditional Access policy prevents the principal from authenticating\
\ to the B2C tenant's MS Graph endpoint."
confidence: 0.7
derived_from:
- azure-b2c-keyset-admin-role (explicit)
false_positive_note: The MS Graph API /beta/trustFramework/keysets/{id}/uploadSecret allows importing
an attacker-supplied PEM-encoded signing key. If only the generateKey API is available, downgrade
to POTENTIAL(key_permission) because the attacker adds a key they cannot use offline. B2C IEF Keyset
Administrator requires a directory role INSIDE the B2C tenant, not ARM permissions on the subscription.
The attack is only ACTIVE if the uploadSecret path is confirmed available.
narrative: '{principal.name} holds the B2C IEF Keyset Administrator (or Global Admin) role and can replace
the signing keyset {keyset.name} used by B2C custom policies via POST /beta/trustFramework/keysets/{id}/uploadSecret
(Policy.ReadWrite.TrustFramework). Replacing the signing key with an attacker-controlled key allows
forging tokens accepted by all relying party applications that validate tokens against this B2C tenant.'