> 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_reader.md).

# AZ\_STORAGE\_BLOB\_DATA\_READER

## Summary

|                            |                                      |
| -------------------------- | ------------------------------------ |
| **Forestall ACL Alias**    | AZ\_STORAGE\_BLOB\_DATA\_READER      |
| **Azure Alias**            | Storage Blob Data Reader             |
| **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/read`
* `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/*`

## Built-In Role Coverage

The edge implementation maps Azure RBAC roles that grant blob read through `DataActions`. This does not include management-plane roles such as Owner unless they also grant blob data-plane actions directly.

Roles with direct blob read data action:

* Avere Contributor (`4f8fab4f-1852-4a58-a46a-8eaf358af14a`)
* Avere Operator (`c025889f-8102-4ebf-b32c-fc0c6f0c6bd9`)
* Azure Center for SAP solutions administrator (`7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7`)
* Azure Red Hat OpenShift Image Registry Operator (`8b32b316-c2f5-4ddf-b05b-83dacd2d08b5`)
* CosmosDB Fleet Analytics Storage Data Writer (`bf41e52e-617f-4981-8b7a-47431bd4e011`)
* Defender for Storage Data Scanner (`1e7ca9b1-60d1-4db8-a914-f2ca1ff27c40`)
* Defender Sensitive Data Discovery (`0b6ca2e8-2cdc-4bd6-b896-aa3d8c21fc35`)
* Defender Storage Malware Data Scanner (`cd50fd1f-0421-46f2-8cce-afc587dbcc77`)
* Storage Actions Blob Data Operator (`4bad4d9e-2a13-4888-94bb-c8432f6f3040`)
* Storage Blob Data Contributor (`ba92f5b4-2d11-453d-a403-e96b0029c9fe`)
* Storage Blob Data Reader (`2a2b9908-6ea1-4ae2-8e65-a410df84e7d1`)
* Storage Connector Contributor (`9d819e60-1b9f-4871-b492-4e6cdee0b50a`)
* Storage DataShare Contributor (`35c49d44-ccc1-4b18-8267-cfb3bacdd396`)
* VM Restore Operator (`dfce8971-25e3-42e3-ba33-6055438e3080`)

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

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

## Description

`AZ_STORAGE_BLOB_DATA_READER` represents data-plane permission to read blob data from an Azure Storage Account. The `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` data action can read a blob or list blobs inside an accessible container; listing containers requires the separate `Microsoft.Storage/storageAccounts/blobServices/containers/read` control-plane action. Blob contents may contain sensitive files, backups, logs, source code, deployment packages, or credentials.

This edge is high impact because blob containers are frequently used as durable storage for application data and operational artifacts. Read access alone may be enough to recover secrets, extract backups, or collect files that enable lateral movement.

Related edges: [AZ\_STORAGE\_BLOB\_DATA\_WRITER](https://docs.forestall.io/fsprotect/edges/azure/az_storage_blob_data_writer), [AZ\_STORAGE\_LIST\_KEYS](https://docs.forestall.io/fsprotect/edges/azure/az_storage_list_keys), [AZ\_STORAGE\_SAS\_GENERATE](https://docs.forestall.io/fsprotect/edges/azure/az_storage_sas_generate).

## Identification

### PowerShell (Az Module)

```powershell
Connect-AzAccount

$blobReadDataActions = @(
    "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read"
)

$blobReadRoleDefinitions = Get-AzRoleDefinition | Where-Object {
    $hasBlobReadDataAction = $false
    $permissionSets = @($_.Permissions | Where-Object { $null -ne $_ })
    $flattenedDataActions = @($_.DataActions | Where-Object { $null -ne $_ })
    $flattenedNotDataActions = @($_.NotDataActions | Where-Object { $null -ne $_ })

    if ($flattenedDataActions.Count -gt 0 -or $flattenedNotDataActions.Count -gt 0) {
        $permissionSets +=
            [PSCustomObject]@{
                DataActions = $flattenedDataActions
                NotDataActions = $flattenedNotDataActions
            }
    }

    foreach ($permission in $permissionSets) {
        $grantedDataActions = @($permission.DataActions)
        $blockedDataActions = @($permission.NotDataActions)

        foreach ($blobReadDataAction in $blobReadDataActions) {
            $isGranted = @($grantedDataActions | Where-Object { $blobReadDataAction -like $_ }).Count -gt 0
            $isBlocked = @($blockedDataActions | Where-Object { $blobReadDataAction -like $_ }).Count -gt 0

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

    $hasBlobReadDataAction
}

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

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

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

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

$blobReadAssignments |
    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 read data actions.
4. Check inherited assignments from parent scopes.

## Exploitation

These examples are for authorized testing only.

### List Containers and Blobs with Entra Authentication

```bash
az login

# Requires Microsoft.Storage/storageAccounts/blobServices/containers/read.
az storage container list \
    --account-name "<AccountName>" \
    --auth-mode login \
    -o table
```

![list Contrainers](https://3408039743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FObpV44hoVkNmo5bFuVVL%2Fuploads%2Fgit-blob-f99746635842bb4363a7a6cb426139d9ec8ab75c%2Fazure-az_storage_blob_data_reader-list_containers.png?alt=media)

```bash
# Requires Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read.
az storage blob list \
    --account-name "<AccountName>" \
    --container-name "<ContainerName>" \
    --auth-mode login \
    -o table
```

![list blobs](https://3408039743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FObpV44hoVkNmo5bFuVVL%2Fuploads%2Fgit-blob-7bff37c2ce60d381db98e1536bbda5375e9fbc05%2Fazure-az_storage_blob_data_reader-list_blob.png?alt=media)

### Download Blob Contents

```bash
az storage blob download \
    --account-name "<AccountName>" \
    --container-name "<ContainerName>" \
    --name "<BlobName>" \
    --file ".\\downloaded-blob" \
    --auth-mode login
```

![Download blob content](https://3408039743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FObpV44hoVkNmo5bFuVVL%2Fuploads%2Fgit-blob-6bdc97364d25fc55c22ca2c386ed360074b022db%2Fazure-az_storage_blob_data_reader-download_file_from_blob.png?alt=media)

### PowerShell

```powershell
Connect-AzAccount

$ctx = New-AzStorageContext -StorageAccountName "<AccountName>" -UseConnectedAccount
Get-AzStorageContainer -Context $ctx
Get-AzStorageBlob -Context $ctx -Container "<ContainerName>"
Get-AzStorageBlobContent -Context $ctx -Container "<ContainerName>" -Blob "<BlobName>" -Destination ".\downloaded-blob"
```

## Mitigation

1. **Apply least privilege** - assign blob read access only at the narrowest required container scope.
2. **Use time-bound access** through PIM or temporary role assignments for administrative reads.
3. **Separate sensitive containers** and avoid broad storage-account-level blob data assignments.
4. **Use private endpoints and storage firewall rules** to reduce exposure from compromised identities.
5. **Classify and encrypt sensitive data** and avoid storing credentials in blob content.

## Detection

Use the Azure Portal:

1. Open **Azure Portal** -> target **Storage account** -> **Monitoring** -> **Logs**.
2. Review `StorageBlobLogs` for read operations such as `GetBlob`, `GetBlobProperties`, and `ListBlobs`.
3. Correlate blob reads with Microsoft Entra sign-in logs for the calling principal.
4. Alert on bulk downloads, reads from unusual locations, and first-time access to sensitive containers.
5. Review IAM changes that granted blob data roles shortly before read activity.

## References

* [Storage Blob Data Reader built-in role](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/storage#storage-blob-data-reader)
* [Authorize access to blobs using Microsoft Entra ID](https://learn.microsoft.com/en-us/azure/storage/blobs/authorize-access-azure-active-directory)
* [Azure Storage monitoring data reference](https://learn.microsoft.com/en-us/azure/storage/blobs/monitor-blob-storage-reference)
* [`az storage blob download`](https://learn.microsoft.com/en-us/cli/azure/storage/blob#az-storage-blob-download)
