# AZ\_MG\_SERVICEPRINCIPALENDPOINT\_READWRITE\_ALL

## Summary

|                               |                                                                |
| ----------------------------- | -------------------------------------------------------------- |
| **FSProtect ACL Alias**       | AZ\_MG\_SERVICEPRINCIPALENDPOINT\_READWRITE\_ALL               |
| **Entra ID (Azure AD) Alias** | ServicePrincipalEndpoint.ReadWrite.All                         |
| **Affected Object Types**     | Service Principals                                             |
| **Exploitation Certainty**    | Certain                                                        |
| **Graph Permission / Role**   | Application Permission: ServicePrincipalEndpoint.ReadWrite.All |

## Description

`AZ_MG_SERVICEPRINCIPALENDPOINT_READWRITE_ALL` represents a Microsoft Graph application permission that grants the ability to **read and write service principal properties** including endpoints and owners.

**Capabilities (verified):**

* **Add owners** to service principals
* **Modify endpoint URLs** including reply URLs and redirect URIs
* **Update service principal properties**
* **Read service principal configurations**

**Security Implications:**

This permission is dangerous because an attacker can:

* **Add themselves as owner** of a service principal for persistence
* **Redirect authentication flows** by modifying redirect URIs to capture OAuth tokens
* **Token theft** by adding malicious reply URLs to steal access tokens
* **Persistence** through backdoor endpoints that remain after credential rotation

**Comparison with similar permissions:**

| Permission                             | Modify replyUrls | Add Owners | Add Credentials |
| -------------------------------------- | ---------------- | ---------- | --------------- |
| ServicePrincipalEndpoint.ReadWrite.All | Yes              | Yes        | No              |
| Application.ReadWrite.All              | Yes              | Yes        | Yes             |
| Directory.ReadWrite.All                | Yes              | Yes        | Yes             |

## Identification

### PowerShell (Microsoft Graph)

**Find Service Principals with ServicePrincipalEndpoint.ReadWrite.All:**

```powershell
Connect-MgGraph -Scopes "Application.Read.All","Directory.Read.All"

# ServicePrincipalEndpoint.ReadWrite.All permission ID (correct GUID)
$permissionId = "89c8469c-83ad-45f7-8ff2-6e3d4285709e"

# Get Microsoft Graph service principal (resource)
$graphSp = Get-MgServicePrincipal -Filter "appId eq '00000003-0000-0000-c000-000000000000'"

# Find all app role assignments for this permission
Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $graphSp.Id -All | Where-Object { $_.AppRoleId -eq $permissionId } | ForEach-Object {
    $sp = Get-MgServicePrincipal -ServicePrincipalId $_.PrincipalId
    [PSCustomObject]@{
        DisplayName      = $sp.DisplayName
        AppId            = $sp.AppId
        ServicePrincipalId = $sp.Id
        Permission       = "ServicePrincipalEndpoint.ReadWrite.All"
        AssignedDate     = $_.CreatedDateTime
    }
} | Format-Table -AutoSize
```

### Azure GUI

1. Open **Microsoft Entra admin center** -> **Applications** -> **Enterprise applications**
2. Select an application -> **Permissions**
3. Look for **ServicePrincipalEndpoint.ReadWrite.All** in granted permissions

## Exploitation

An attacker with `ServicePrincipalEndpoint.ReadWrite.All` can add owners and modify service principal endpoints.

For adding owners to service principals, see [AZ\_ADD\_OWNER](https://gitlab.com/forestall/fsprotect-knowledge-base/-/blob/main/edges/AZ_ADD_OWNER/README.md).

### Common Abuse Patterns

* Add attacker as owner for persistent access
* Modify redirect URIs to intercept OAuth tokens
* Changes persist after credential rotation

## Mitigation

* **Audit service principals** with `ServicePrincipalEndpoint.ReadWrite.All` and remove unnecessary grants
  * Go to **Microsoft Entra ID** -> **App registrations** -> select application -> **API permissions**
  * Remove the permission if not required
* **Monitor owner additions** on service principals:
  * Alert on new owners added to sensitive service principals
  * Review audit logs for owner changes
* **Implement strict reply URL policies**:
  * Use exact match redirect URIs instead of wildcards
  * Limit reply URLs to known, trusted domains
  * Block localhost and HTTP (non-HTTPS) redirect URIs in production
* **Monitor redirect URI changes** on service principals:
  * Review audit logs for modifications to service principal configurations
  * Alert on unexpected reply URL additions
* **Regular audits**: Periodically review service principal owners and endpoints

## Detection

Detect owner additions and endpoint modifications in **Audit logs**.

### PowerShell (Microsoft Graph)

```powershell
Connect-MgGraph -Scopes "AuditLog.Read.All"

# Detect owner additions and endpoint changes
Get-MgAuditLogDirectoryAudit -Filter "activityDisplayName eq 'Add owner to service principal' or activityDisplayName eq 'Update service principal'" -Top 50 | ForEach-Object {
    [PSCustomObject]@{
        DateTime = $_.ActivityDateTime
        Activity = $_.ActivityDisplayName
        Actor    = $_.InitiatedBy.User.UserPrincipalName ?? $_.InitiatedBy.App.DisplayName
        Target   = $_.TargetResources[0].DisplayName
    }
} | Format-Table -AutoSize
```

### Azure GUI

* Go to **Microsoft Entra ID** -> **Audit logs**
* Filter by activities:
  * **Add owner to service principal**
  * **Update service principal**

### Alert Criteria

* New owners added to service principals
* Reply URL additions to service principals
* Endpoint changes outside change management windows
* Addition of external or suspicious domains to redirect URIs

## References

* <https://learn.microsoft.com/en-us/graph/api/resources/serviceprincipal>
* <https://learn.microsoft.com/en-us/graph/permissions-reference>
* <https://learn.microsoft.com/en-us/entra/identity-platform/reply-url>
* <https://learn.microsoft.com/en-us/graph/api/serviceprincipal-post-owners>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.forestall.io/fsprotect/edges/azure/az_mg_serviceprincipalendpoint_readwrite_all.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
