detecting-misconfigured-azure-storage について
Azure 管理者やセキュリティ監査担当者向けのストレージ設定監査スキルです。サブスクリプションをまたいで、匿名公開アクセス、ネットワーク制限、暗号化、アクセスキー、診断ログを確認します。
主な機能
- 01サブスクリプション横断のアカウント列挙
- 02Blob の匿名公開アクセス確認
- 03ネットワーク規則とファイアウォールの監査
- 04暗号化とキー管理の確認
- 05SAS、アクセスキー、診断設定の確認
活用シーン
- 01複数サブスクリプションのストレージ監査
- 02公開 Blob による情報露出の調査
- 03暗号化、ネットワーク、ログの準拠確認
- 04新規サブスクリプションの基準設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill detecting-misconfigured-azure-storageインストール後、Claude Code で/detecting-misconfigured-azure-storageを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/api-reference.mdscripts/agent.py詳細
設定ミスのある Azure Storage の検出
使用するタイミング
- 複数のサブスクリプションにまたがる Azure Storage アカウントのセキュリティ監査を実施するとき
- 匿名アクセスやデータ流出に関する Microsoft Defender for Storage のアラートに対応するとき
- コンプライアンス要件により、暗号化、ネットワーク制限、アクセスログ記録の検証が必要なとき
- 公開アクセス可能な blob コンテナーを通じたデータ露出の可能性を調査するとき
- Azure サブスクリプションをオンボーディングし、ストレージのセキュリティベースラインを策定するとき
使用しないでください Azure SQL や Cosmos DB のセキュリティ監査には(専用のデータベースセキュリティツールを使用してください)、ストレージ操作のリアルタイムの脅威検出には(Defender for Storage を使用してください)、また、チェック内容を調整せずに Azure Files や Data Lake Gen2 固有の監査を行う場合には使用しないでください。
前提条件
- Reader および Storage Account Contributor ロールを持ち、認証済みの Azure CLI がインストールされていること(
az login) - 高度なクエリ用に Az PowerShell モジュールがインストールされていること(
Install-Module Az.Storage) - 脅威検出のために Microsoft Defender for Storage が有効になっていること
- サブスクリプションをまたぐクエリのために Azure Resource Graph にアクセスできること
- 自動評価のために ScoutSuite または Prowler Azure プロバイダーが利用可能であること
ワークフロー
ステップ 1: すべてのストレージアカウントと基本構成の列挙
すべてのサブスクリプションのストレージアカウントを一覧表示し、基本的なセキュリティ設定を評価します。
# List all storage accounts across all subscriptions
az storage account list \
--query "[].{Name:name, ResourceGroup:resourceGroup, Location:location, Kind:kind, Sku:sku.name, HttpsOnly:enableHttpsTrafficOnly, MinTLS:minimumTlsVersion, PublicAccess:allowBlobPublicAccess}" \
-o table
# Use Resource Graph for cross-subscription enumeration
az graph query -q "
Resources
| where type == 'microsoft.storage/storageaccounts'
| project name, resourceGroup, subscriptionId, location,
properties.allowBlobPublicAccess,
properties.enableHttpsTrafficOnly,
properties.minimumTlsVersion,
properties.networkAcls.defaultAction
" -o table
ステップ 2: 公開アクセス可能な blob コンテナーの検出
blob データへの匿名の公開アクセスを許可しているストレージアカウントとコンテナーを特定します。
# Check each storage account for public blob access setting
for account in $(az storage account list --query "[].name" -o tsv); do
public=$(az storage account show --name "$account" --query "allowBlobPublicAccess" -o tsv)
echo "$account: allowBlobPublicAccess=$public"
done
# List containers with public access level set
for account in $(az storage account list --query "[?allowBlobPublicAccess==true].name" -o tsv); do
key=$(az storage account keys list --account-name "$account" --query "[0].value" -o tsv)
echo "=== $account ==="
az storage container list \
--account-name "$account" \
--account-key "$key" \
--query "[?properties.publicAccess!='off' && properties.publicAccess!=null].{Container:name, PublicAccess:properties.publicAccess}" \
-o table 2>/dev/null
done
# Test anonymous access to discovered public containers
curl -s "https://ACCOUNT.blob.core.windows.net/CONTAINER?restype=container&comp=list" | head -50
ステップ 3: ネットワークアクセスとファイアウォールルールの監査
すべてのネットワークからアクセス可能なストレージアカウントと、特定の VNet や IP 範囲に制限されたストレージアカウントを確認します。
# Find storage accounts with default network action set to Allow (open to all networks)
az storage account list \
--query "[?networkRuleSet.defaultAction=='Allow'].{Name:name, DefaultAction:networkRuleSet.defaultAction, VNetRules:networkRuleSet.virtualNetworkRules}" \
-o table
# Detailed network rule audit
for account in $(az storage account list --query "[].name" -o tsv); do
echo "=== $account ==="
az storage account show --name "$account" \
--query "{DefaultAction:networkRuleSet.defaultAction, IPRules:networkRuleSet.ipRules[*].ipAddressOrRange, VNetRules:networkRuleSet.virtualNetworkRules[*].virtualNetworkResourceId, Bypass:networkRuleSet.bypass}" \
-o json
done
# Find storage accounts with private endpoints
az network private-endpoint list \
--query "[?privateLinkServiceConnections[0].groupIds[0]=='blob'].{Name:name, Storage:privateLinkServiceConnections[0].privateLinkServiceId}" \
-o table
ステップ 4: 暗号化設定とキー管理の検証
すべてのストレージアカウントが、適切なキー管理(Microsoft 管理キーまたは顧客管理キー)を用いて保存時の暗号化を使用していることを確認します。
# Check encryption configuration for all storage accounts
for account in $(az storage account list --query "[].name" -o tsv); do
echo "=== $account ==="
az storage account show --name "$account" \
--query "{Encryption:encryption.services, KeySource:encryption.keySource, KeyVaultUri:encryption.keyVaultProperties.keyVaultUri, InfraEncryption:encryption.requireInfrastructureEncryption}" \
-o json
done
# Find accounts without infrastructure encryption (double encryption)
az storage account list \
--query "[?encryption.requireInfrastructureEncryption!=true].{Name:name, KeySource:encryption.keySource}" \
-o table
# Check for accounts using TLS version below 1.2
az storage account list \
--query "[?minimumTlsVersion!='TLS1_2'].{Name:name, TLS:minimumTlsVersion}" \
-o table
ステップ 5: Shared Access Signature とアクセスキーの監査
過度に許可的な SAS トークンを特定し、アクセスキーの使用パターンを確認します。
# Check when storage account keys were last rotated
for account in $(az storage account list --query "[].name" -o tsv); do
echo "=== $account ==="
az storage account keys list \
--account-name "$account" \
--query "[].{KeyName:keyName, CreationTime:creationTime}" \
-o table
done
# Check if storage account allows shared key access (should be disabled for AAD-only)
az storage account list \
--query "[].{Name:name, AllowSharedKeyAccess:allowSharedKeyAccess}" \
-o table
# Review stored access policies on containers (SAS governance)
for account in $(az storage account list --query "[].name" -o tsv); do
key=$(az storage account keys list --account-name "$account" --query "[0].value" -o tsv 2>/dev/null)
for container in $(az storage container list --account-name "$account" --account-key "$key" --query "[].name" -o tsv 2>/dev/null); do
policies=$(az storage container policy list --container-name "$container" --account-name "$account" --account-key "$key" 2>/dev/null)
[ -n "$policies" ] && echo "$account/$container: $policies"
done
done
ステップ 6: 診断ログ記録と監視の確認
ストレージ分析ログと Azure Monitor の診断設定が有効になっていることを確認します。
# Check diagnostic settings for storage accounts
for account in $(az storage account list --query "[].name" -o tsv); do
rg=$(az storage account show --name "$account" --query "resourceGroup" -o tsv)
echo "=== $account ==="
az monitor diagnostic-settings list \
--resource "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/$rg/providers/Microsoft.Storage/storageAccounts/$account" \
--query "[].{Name:name, Logs:logs[*].category, Metrics:metrics[*].category}" \
-o json 2>/dev/null || echo " No diagnostic settings configured"
done
# Check blob service logging properties
for account in $(az storage account list --query "[].name" -o tsv); do
key=$(az storage account keys list --account-name "$account" --query "[0].value" -o tsv 2>/dev/null)
az storage logging show \
--account-name "$account" \
--account-key "$key" \
--services b 2>/dev/null
done
主要な概念
| 用語 | 定義 |
|---|---|
| Blob Public Access | 認証なしで、blob コンテナーとそのコンテンツへの匿名の読み取りアクセスを許可するストレージアカウントの設定 |
| Shared Access Signature | 認証トークンを埋め込んだ期間限定の URI で、特定の権限により Azure Storage リソースへの委任アクセスを付与する仕組み |
| Network ACL Default Action | 指定された IP や VNet を例外として、トラフィックをデフォルトで許可するか拒否するかを決定するストレージファイアウォールの設定 |
| Customer-Managed Key | Microsoft 管理キーの代わりに、ストレージの暗号化に顧客が管理する Azure Key Vault 内のキー |
| Stored Access Policy | コンテナーに対する名前付きポリシーで、SAS の権限と開始/有効期限を定義し、個々の SAS トークンとは独立して取り消すことができる |
| Defender for Storage | 異常なストレージアクセスパターン、マルウェアのアップロード、データ流出に対する脅威検出を提供する Microsoft Defender のプラン |
ツールとシステム
- Azure CLI: ストレージアカウントの構成、コンテナー、アクセスポリシーを照会するための主要ツール
- Azure Resource Graph: 大規模なストレージセキュリティ設定を効率的に列挙するためのサブスクリプションをまたぐクエリエンジン
- Microsoft Defender for Storage: 異常なアクセスパターンとデータ流出の可能性を特定する脅威検出サービス
- Prowler Azure: CIS Azure Foundations に準拠した自動ストレージセキュリティチェックを備えるオープンソースツール
- ScoutSuite: パブリックアクセス、暗号化、ネットワークに関する Azure ストレージ固有のチェックを備えたマルチクラウド監査ツール
よくあるシナリオ
シナリオ: 開発者の設定ミスによって公開されたストレージアカウントの検出
背景: 開発者が Web アプリケーション用にストレージアカウントを作成し、静的ファイルを配信するために BLOB のパブリックアクセスを有効にします。その際、誤って API キーとデータベース接続文字列を公開アクセス可能なコンテナーに保存してしまいます。
手順:
allowBlobPublicAccess=trueでフィルタリングしながらaz storage account listを実行する- パブリックアクセスレベルが
blobまたはcontainerに設定されているコンテナーを列挙する - 公開コンテナーの内容を一覧表示し、機密ファイルを特定する
- Defender for Storage のアラートを確認し、想定外の IP アドレスからの異常なアクセスがないかを調べる
- ストレージアカウントの
allowBlobPublicAccessを直ちにfalseに設定する - 公開コンテナーで見つかった漏えいした認証情報をすべてローテーションする
- アプリケーションの VNet からのアクセスのみを許可するようネットワーク ACL を有効にする
- 正当な公開コンテンツの配信のために Azure CDN または Front Door を構成する
注意点: BLOB のパブリックアクセスを直ちに無効にすると、コンテンツを公開で配信しているアプリケーションが動作しなくなります。開発チームと調整し、パブリックアクセスを無効にする前に Azure CDN を導入してください。キーのローテーション前に生成された SAS トークンは、基盤となるストレージキーを再生成しない限り、有効期限が切れるまで有効なままです。
出力形式
Azure Storage Security Audit Report
======================================
Subscription: Production (SUB-ID)
Assessment Date: 2026-02-23
Storage Accounts Audited: 24
CRITICAL FINDINGS:
[STOR-001] Public Blob Access Enabled
Account: webapp-static-prod
Container: uploads (PublicAccess: blob)
Risk: Anonymous users can read all blobs in the container
Contents: 1,247 files including .env and config.json
Remediation: Disable allowBlobPublicAccess, use Azure CDN with SAS
[STOR-002] Storage Account Open to All Networks
Account: data-lake-analytics
Default Action: Allow (no network restrictions)
Risk: Accessible from any network including the internet
Remediation: Set default action to Deny, add VNet rules
SUMMARY:
Public blob access enabled: 3 / 24
Open to all networks: 8 / 24
Missing infrastructure encryption: 12 / 24
TLS version below 1.2: 2 / 24
No diagnostic logging: 10 / 24
Shared key access enabled: 18 / 24
Keys not rotated in 90+ days: 14 / 24