prowler-cloud/prowler
View on GitHub[New Check]: Microsoft Entra directory sync must block object takeover (soft- and hard-matching)
Open
#11068 opened on May 6, 2026
feature-requestgood first issuenew-checkprovider/m365
Description
Existing check search
- I have searched existing issues, Prowler Hub, and the public roadmap, and this check does not already exist.
Provider
Microsoft 365
New provider name
No response
Service or product area
entra
Suggested check name
entra_directory_sync_object_takeover_blocked
Context and goal
- Security condition to validate: When the tenant has on-premises directory synchronization enabled, the tenant must block the two synchronization paths that allow an on-premises object to take over an existing cloud object — both
features.blockSoftMatchEnabledandfeatures.blockCloudObjectTakeoverThroughHardMatchEnabledononPremisesDirectorySynchronizationmust betrue. - Why it matters: When an on-premises synchronized object reaches Microsoft Entra ID, the sync engine can attach it to an existing cloud object via two matching modes — one based on
userPrincipalNameor primary SMTP address, and one based onImmutableID/ source anchor. An attacker (or a careless operator) able to write to on-premises Active Directory can craft an object that matches a privileged cloud account, e.g. a Global Administrator, and effectively take it over. Microsoft documents this as one of the highest-impact hybrid identity attack paths and ships the two block flags specifically to neutralise it. Operators are expected to keep both blocks on permanently outside time-boxed migrations; this check enforces that. - Resource involved: Microsoft Entra
onPremisesDirectorySynchronizationresource and itsfeaturescollection.
Expected behavior
- Resource or scope to evaluate: The single
onPremisesDirectorySynchronizationobject for the tenant —GET https://graph.microsoft.com/v1.0/directory/onPremisesSynchronization. Readfeatures.blockSoftMatchEnabledandfeatures.blockCloudObjectTakeoverThroughHardMatchEnabled. - PASS when: both
features.blockSoftMatchEnabled = trueANDfeatures.blockCloudObjectTakeoverThroughHardMatchEnabled = true. - FAIL when: either flag is
false. The finding should report which flag(s) are off. - MANUAL when: the calling identity does not have permission to read
onPremisesDirectorySynchronization(Graph returns 403). Mark MANUAL with a status message asking the operator to grant the required scope and re-run. - Exclusions / edge cases:
- Skip when on-premises sync is not configured. Read the tenant's
organization.onPremisesSyncEnabledfirst; iffalse(cloud-only tenant), the check does not apply — emit MANUAL or skip with a clear status message rather than FAIL on a missingonPremisesSynchronizationobject. - Do not treat a transient 5xx / throttling response as a FAIL — only a definitive
falsevalue counts.
- Skip when on-premises sync is not configured. Read the tenant's
References
- Microsoft Graph v1.0 —
onPremisesDirectorySynchronizationresource: https://learn.microsoft.com/en-us/graph/api/resources/onpremisesdirectorysynchronization?view=graph-rest-1.0 - Microsoft Graph v1.0 —
onPremisesDirectorySynchronizationFeature(blockSoftMatchEnabled,blockCloudObjectTakeoverThroughHardMatchEnabled): https://learn.microsoft.com/en-us/graph/api/resources/onpremisesdirectorysynchronizationfeature?view=graph-rest-1.0 - Microsoft Entra Connect Sync — sync service features (soft match / hard match guidance): https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/how-to-connect-syncservice-features
Suggested severity
Medium
Additional implementation notes
- Existing patterns to follow: Sibling checks
entra_password_hash_sync_enabledandentra_seamless_sso_disabledalready inspect on-premises directory synchronization state; they live underprowler/providers/m365/services/entra/. Reuse the same loading pattern inentra_service.pyand add the twofeatures.*booleans to the existingOnPremisesDirectorySynchronizationmodel (or introduce one if it does not yet exposefeatures). - Permissions / scopes: No additional permissions beyond Prowler's M365 baseline.
Directory.Read.Allalready grants reads againstonPremisesSynchronizationandorganization. The optional alternativeOnPremDirectorySynchronization.Read.All(used byentra_seamless_sso_disabled) also covers this surface. - PowerShell is NOT needed; the check uses Microsoft Graph v1.0 only.
- Related checks (do NOT duplicate):
entra_password_hash_sync_enabled(PHS) andentra_seamless_sso_disabledaudit differentonPremisesSynchronizationfeatures; this check is additive and should not interfere with them. - Metadata: follow the M365 metadata schema used by sibling checks under
entra/.