> For the complete documentation index, see [llms.txt](https://docs.forestall.io/forestall/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.forestall.io/forestall/edges/azure/az_storage_blob_data_writer.md).

# AZ\_STORAGE\_BLOB\_DATA\_WRITER

## Summary

|                            |                                      |
| -------------------------- | ------------------------------------ |
| **Forestall ACL Alias**    | AZ\_STORAGE\_BLOB\_DATA\_WRITER      |
| **Azure Alias**            | Storage Blob Data Writer             |
| **Affected Object Types**  | Storage Accounts / Blob Containers   |
| **Exploitation Certainty** | Certain                              |
| **Severity**               | High                                 |
| **Azure RBAC Roles**       | See **Built-In Role Coverage** below |

**Custom Role Data Actions:**

* `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write`
* `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete`
* `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/add/action`
* `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/move/action`
* `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/*`

## Built-In Role Coverage

The edge implementation maps Azure RBAC roles that can modify blob data through `DataActions`. This includes content writes, adds, moves, deletes, tag writes, and privileged blob data operations. It does not include management-plane roles such as Owner unless they also grant blob data-plane actions directly.

Roles with direct blob modification data actions:

* Avere Contributor (`4f8fab4f-1852-4a58-a46a-8eaf358af14a`) - `blobs/delete`, `blobs/read`, `blobs/write`.
* Avere Operator (`c025889f-8102-4ebf-b32c-fc0c6f0c6bd9`) - `blobs/delete`, `blobs/read`, `blobs/write`.
* Azure Red Hat OpenShift Image Registry Operator (`8b32b316-c2f5-4ddf-b05b-83dacd2d08b5`) - `blobs/add/action`, `blobs/delete`, `blobs/move/action`, `blobs/read`, `blobs/write`.
* CosmosDB Fleet Analytics Storage Data Writer (`bf41e52e-617f-4981-8b7a-47431bd4e011`) - `blobs/add/action`, `blobs/delete`, `blobs/read`, `blobs/write`.
* Defender for Storage Data Scanner (`1e7ca9b1-60d1-4db8-a914-f2ca1ff27c40`) - `blobs/delete`, `blobs/read`, `blobs/tags/read`, `blobs/tags/write`.
* Defender Storage Automated Malware Remediation (`c6c9b2d8-9a5e-4122-85e1-81612a046ab2`) - `blobs/delete`.
* Storage Actions Blob Data Operator (`4bad4d9e-2a13-4888-94bb-c8432f6f3040`) - `blobs/add/action`, `blobs/delete`, `blobs/immutableStorage/runAsSuperUser/action`, `blobs/read`, `blobs/runAsSuperUser/action`, `blobs/tags/read`, `blobs/tags/write`, `blobs/write`.
* Storage Blob Data Contributor (`ba92f5b4-2d11-453d-a403-e96b0029c9fe`) - `blobs/add/action`, `blobs/delete`, `blobs/move/action`, `blobs/read`, `blobs/write`.
* Storage Connector Contributor (`9d819e60-1b9f-4871-b492-4e6cdee0b50a`) - `blobs/read`, `blobs/write`.
* VM Restore Operator (`dfce8971-25e3-42e3-ba33-6055438e3080`) - `blobs/add/action`, `blobs/delete`, `blobs/read`, `blobs/write`.

Roles with wildcard blob data actions that also cover blob modification:

* Storage Blob Data Owner (`b7e6dc6d-f1e8-4753-8033-0f276bb0955b`) - includes `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/*`.

## Description

`AZ_STORAGE_BLOB_DATA_WRITER` represents data-plane permission to write, add, move, delete, update tags, or perform privileged operations against blob data in an Azure Storage Account. In addition to the read impact covered by [AZ\_STORAGE\_BLOB\_DATA\_READER](https://docs.forestall.io/fsprotect/edges/azure/az_storage_blob_data_reader), this edge can let an attacker overwrite application content, replace deployment artifacts, delete evidence, stage payloads, or corrupt backups.

This edge is high impact because blob storage often feeds downstream workloads such as App Service deployments, Function packages, data pipelines, backup restoration, static websites, and containerized applications that pull configuration or content from storage.

## Identification

### PowerShell (Az Module)

```powershell
Connect-AzAccount

$blobModifyDataActions = @(
    "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write",
    "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete",
    "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/add/action",
    "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/move/action"
)

$blobModifyRoleDefinitions = Get-AzRoleDefinition | Where-Object {
    $hasMatch = $false

    foreach ($permission in $_.Permissions) {
        $grantedDataActions = @($permission.DataActions | Where-Object { $_ })
        $blockedDataActions = @($permission.NotDataActions | Where-Object { $_ })

        foreach ($targetAction in $blobModifyDataActions) {
            $isGranted = $false
            $isBlocked = $false

            foreach ($grantedAction in $grantedDataActions) {
                # Handle wildcards: *, Microsoft.Storage/*, etc.
                $pattern = "^" + [regex]::Escape($grantedAction).Replace("\*", ".*") + "$"
                if ($targetAction -match $pattern) { $isGranted = $true }
            }

            foreach ($blockedAction in $blockedDataActions) {
                $pattern = "^" + [regex]::Escape($blockedAction).Replace("\*", ".*") + "$"
                if ($targetAction -match $pattern) { $isBlocked = $true }
            }

            if ($isGranted -and -not $isBlocked) {
                $hasMatch = $true
                break
            }
        }
        if ($hasMatch) { break }
    }

    $hasMatch
}

$blobModifyRoleDefinitions |
    Select-Object Name, Id |
    Sort-Object Name |
    Format-Table -AutoSize

$blobModifyRoleIds = @(
    $blobModifyRoleDefinitions | ForEach-Object {
        ($_.Id.ToString() -split "/")[-1].ToLowerInvariant()
    }
)

$storageAccountScopes = Get-AzStorageAccount | Select-Object -ExpandProperty Id

$blobModifyAssignments = foreach ($scope in $storageAccountScopes) {
    Get-AzRoleAssignment -Scope $scope |
        Where-Object {
            $roleDefinitionId = ($_.RoleDefinitionId.ToString() -split "/")[-1].ToLowerInvariant()
            $blobModifyRoleIds -contains $roleDefinitionId
        } |
        Select-Object RoleDefinitionName, DisplayName, SignInName, ObjectType, Scope
}

$blobModifyAssignments |
    Select-Object RoleDefinitionName, DisplayName, SignInName, ObjectType, Scope |
    Sort-Object Scope, RoleDefinitionName |
    Format-Table -AutoSize
```

### Azure Portal

1. Open **Azure Portal** -> target **Storage account** or **Container**.
2. Go to **Access control (IAM)** -> **Role assignments**.
3. Review the roles in **Built-In Role Coverage** and custom roles with blob modification data actions.
4. Check inherited assignments from the resource group, subscription, and management group.

## Exploitation

These examples are for authorized testing only.

### Write Abuse

Upload new blobs or overwrite existing content. Use this to replace deployment artifacts, inject malicious payloads, or corrupt application data.

![Write Abuse](https://3408039743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FObpV44hoVkNmo5bFuVVL%2Fuploads%2Fgit-blob-01df3499add0eae9b3a02de9009002d7370d1c4a%2Fazure-az_storage_blob_data_writer-write_abude.PNG?alt=media)

**Azure CLI:**

```bash
az login

az storage blob upload \
    --account-name "<AccountName>" \
    --container-name "<ContainerName>" \
    --name "<BlobName>" \
    --file ".\\payload.bin" \
    --overwrite true \
    --auth-mode login
```

**PowerShell:**

```powershell
Connect-AzAccount

$ctx = New-AzStorageContext -StorageAccountName "<AccountName>" -UseConnectedAccount
Set-AzStorageBlobContent -Context $ctx -Container "<ContainerName>" -File ".\payload.bin" -Blob "<BlobName>" -Force
```

### Delete Abuse

Delete blobs to destroy evidence, disrupt services, or corrupt backups.

![Delete Abuse](https://3408039743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FObpV44hoVkNmo5bFuVVL%2Fuploads%2Fgit-blob-3ce27c4e29d43929a983abea6929b7eb2ecaa897%2Fazure-az_storage_blob_data_writer-Delete_abuse.PNG?alt=media)

**Azure CLI:**

```bash
az storage blob delete \
    --account-name "<AccountName>" \
    --container-name "<ContainerName>" \
    --name "<BlobName>" \
    --auth-mode login
```

**PowerShell:**

```powershell
Connect-AzAccount

$ctx = New-AzStorageContext -StorageAccountName "<AccountName>" -UseConnectedAccount
Remove-AzStorageBlob -Context $ctx -Container "<ContainerName>" -Blob "<BlobName>"
```

### Move Abuse

Move blobs between containers to exfiltrate data to an attacker-controlled container, bypass access controls, or disrupt workflows that depend on specific blob locations.

![Move Abuse](https://3408039743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FObpV44hoVkNmo5bFuVVL%2Fuploads%2Fgit-blob-6d2dab44ac3e4fcea14650791c80eca9ba635eb0%2Fazure-az_storage_blob_data_writer-move_abuse.PNG?alt=media)

**Azure CLI:**

```bash
az storage blob copy start \
    --account-name "<AccountName>" \
    --destination-container "<DestContainerName>" \
    --destination-blob "<DestBlobName>" \
    --source-account-name "<AccountName>" \
    --source-container "<SourceContainerName>" \
    --source-blob "<SourceBlobName>" \
    --auth-mode login

az storage blob delete \
    --account-name "<AccountName>" \
    --container-name "<SourceContainerName>" \
    --name "<SourceBlobName>" \
    --auth-mode login
```

**PowerShell:**

```powershell
Connect-AzAccount

$ctx = New-AzStorageContext -StorageAccountName "<AccountName>" -UseConnectedAccount
$sourceBlob = Get-AzStorageBlob -Context $ctx -Container "<SourceContainerName>" -Blob "<SourceBlobName>"
Start-AzStorageBlobCopy -SrcBlob $sourceBlob.Name -SrcContainer "<SourceContainerName>" -DestContainer "<DestContainerName>" -DestBlob "<DestBlobName>" -Context $ctx
Remove-AzStorageBlob -Context $ctx -Container "<SourceContainerName>" -Blob "<SourceBlobName>"
```

## Mitigation

1. **Limit write access** - assign blob modification permissions only to identities that must modify data.
2. **Scope assignments to containers** instead of full storage accounts where possible.
3. **Enable blob versioning and soft delete** to recover from malicious overwrite or deletion.
4. **Use immutable storage policies** for backups, logs, and regulated data.
5. **Separate deployment artifacts from general storage** and protect production containers with stricter approval workflows.

## Detection

Use the Azure Portal:

1. Open **Azure Portal** -> target **Storage account** -> **Monitoring** -> **Logs**.
2. Review `StorageBlobLogs` for write/delete operations such as `PutBlob`, `PutBlockList`, `DeleteBlob`, and `SetBlobTier`.
3. Alert on writes to production deployment containers, backup containers, or static website content by unusual principals.
4. Correlate blob writes with IAM changes, Microsoft Entra sign-in logs, and downstream workload restarts or deployments.
5. Review blob version history for unexpected replacements.

## References

* [Storage Blob Data Contributor built-in role](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/storage#storage-blob-data-contributor)
* [Authorize access to blobs using Microsoft Entra ID](https://learn.microsoft.com/en-us/azure/storage/blobs/authorize-access-azure-active-directory)
* [Blob soft delete](https://learn.microsoft.com/en-us/azure/storage/blobs/soft-delete-blob-overview)
* [Immutable storage for Azure Blob Storage](https://learn.microsoft.com/en-us/azure/storage/blobs/immutable-storage-overview)
