Framework/Configurations/SVT/Services/Storage.json

{
  "FeatureName": "Storage",
  "Reference": "aka.ms/azsktcp/storage",
  "IsMaintenanceMode": false,
  "Controls": [
   {
      "ControlID": "Azure_Storage_AuthN_Dont_Allow_Anonymous",
      "Description": "The Access Type for containers must not be set to 'Anonymous'",
      "Id": "AzureStorage110",
      "ControlSeverity": "High",
      "Automated": "Yes",
      "MethodName": "CheckStorageContainerPublicAccessTurnOff",
      "Rationale": "Data in containers that have anonymous access can be downloaded by anyone on the internet without authentication. This can lead to a compromise of corporate data.",
      "Recommendation": "Run command 'Set-AzStorageContainerAcl -Name '<ContainerName>' -Permission 'Off' -Context (New-AzStorageContext -StorageAccountName '<StorageAccountName>' -StorageAccountKey '<StorageAccountKey>')'. Run 'Get-Help Set-AzStorageContainerAcl -full' for more help.",
      "Tags": [
         "SDL",
         "TCP",
         "Automated",
         "AuthN",
         "StandardSku",
         "PremiumSku",
         "GeneralPurposeStorage",
         "BlobStorage",
         "HNSDisabled",
         "ResourceLocked"
      ],
      "Enabled": true,
      "FixControl": {
         "FixMethodName": "DisableAnonymousAccessOnContainers",
         "FixControlImpact": "High"
      },
      "PolicyDefinitionGuid": "34c877ad-507e-4c82-993e-3452a6e0ad3c"
   },
    {
      "ControlID": "Azure_Storage_Audit_Issue_Alert_AuthN_Req",
      "Description": "Alert rules must be configured for tracking anonymous activity",
      "Id": "AzureStorage120",
      "ControlSeverity": "High",
      "Automated": "Yes",
      "MethodName": "CheckStorageMetricAlert",
      "Rationale": "Alert rules for anonymous authentication requests enable you to detect any suspicious and malicious activity early and respond in a timely manner.",
      "Recommendation": "Run command: `$dimension = New-AzMetricAlertRuleV2DimensionSelection -DimensionName 'Authentication' -ValuesToInclude 'Anonymous'. Run Command: `$condition = New-AzMetricAlertRuleV2Criteria -MetricName 'Transactions' -DimensionSelection `$dimension -TimeAggregation Total -Operator GreaterThan -Threshold 0 -MetricNamespace 'Microsoft.Storage/storageAccounts'. Run Command: Add-AzMetricAlertRuleV2 -ActionGroup <ActionGroupId> -Condition `$condition -Name <AlertName> -ResourceGroupName <RG name> -WindowSize 01:00:00 -Frequency 01:00:00 -TargetResourceId <Resource Id> -Severity 3 -WarningAction SilentlyContinue -ErrorAction Stop. To create action group refer https://docs.microsoft.com/en-us/powershell/module/az.monitor/set-azactiongroup?view=azps-2.6.0",
      "Tags": [
        "SDL",
        "TCP",
        "Automated",
        "Audit",
        "StandardSku",
        "GeneralPurposeStorage",
        "BlobStorage"
      ],
      "Enabled": false,
      "FixControl": {
        "FixMethodName": "SetupAlertsForAuthNRequest",
        "FixControlImpact": "Low"
      }
    },
    {
      "ControlID": "Azure_Storage_Audit_AuthN_Requests",
      "Description": "Storage Account must be configured to log and monitor authentication request data",
      "Id": "AzureStorage150",
      "ControlSeverity": "Medium",
      "Automated": "Yes",
      "MethodName": "CheckStorageEnableDiagnosticsLog",
      "Rationale": "Logging and monitoring of authentication request data can help to detect suspicious and malicious activities early and respond in a timely manner.",
      "Recommendation": "First, run the command '`$storageAccount = Get-AzStorageAccount -ResourceGroupName <RGName> -Name <Storage Name> -ErrorAction SilentlyContinue'. Then, run '`$storageContext = `$storageAccount.Context'. This is the value that you need to supply for -Context in the subsequent commands. Run command 'Set-AzStorageServiceLoggingProperty -ServiceType '<Blob/Queue/Table>' -LoggingOperations 'All' -Context `$storageContext -RetentionDays '365' -PassThru'. Run 'Get-Help Set-AzStorageServiceLoggingProperty -full' for more help. Set-AzStorageServiceMetricsProperty -MetricsType 'Hour' -ServiceType '<Blob/Queue/Table/File>' -Context storageContext -MetricsLevel 'ServiceAndApi' -RetentionDays '365' -PassThru. Run 'Get-Help Set-AzStorageServiceMetricsProperty -full' for more help.",
      "Tags": [
         "SDL",
         "TCP",
         "Automated",
         "Audit",
         "OwnerAccess",
         "StandardSku",
         "GeneralPurposeStorage",
         "BlobStorage",
         "ResourceLocked"
      ],
      "Enabled": true,
      "FixControl": {
        "FixMethodName": "EnableAuditOnAuthN",
        "FixControlImpact": "Low"
      }
    },
   {
      "ControlID": "Azure_Storage_DP_Encrypt_In_Transit",
      "Description": "HTTPS protocol must be used for accessing Storage Account resources",
      "Id": "AzureStorage160",
      "ControlSeverity": "High",
      "Automated": "Yes",
      "MethodName": "CheckStorageEncryptionInTransit",
      "Rationale": "Use of HTTPS ensures server/service authentication and protects data in transit from network layer man-in-the-middle, eavesdropping, session-hijacking attacks. When enabling HTTPS one must remember to simultaneously disable access over plain HTTP else data can still be subject to compromise over clear text connections.",
      "Recommendation": "Run command 'Set-AzStorageAccount -ResourceGroupName <RGName> -Name <StorageAccountName> -EnableHttpsTrafficOnly `$true'. Run 'Get-Help Set-AzStorageAccount -full' for more help.",
      "Tags": [
         "SDL",
         "TCP",
         "Automated",
         "DP",
         "StandardSku",
         "PremiumSku",
        "GeneralPurposeStorage",
        "BlobStorage",
        "PremiumFileShareStorage"
      ],
      "PolicyDefinitionGuid":"404c3081-a854-4457-ae30-26a93ef643f9",
      "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/404c3081-a854-4457-ae30-26a93ef643f9",
      "Enabled": true,
      "FixControl": {
         "FixMethodName": "EnableHttpsTrafficOnly",
         "FixControlImpact": "Medium"
      }
   },
    {
      "ControlID": "Azure_Storage_AuthZ_Use_IP_ACL",
      "Description": "Use IP-restrictions in SAS tokens to only permit access from intended IP addresses",
      "Id": "AzureStorage180",
      "ControlSeverity": "Medium",
      "Automated": "No",
      "MethodName": "",
      "Rationale": "Using appropriate IP-based ACLs ensures that data in storage is protected and accessible only to entities from an expected set of endpoints.",
      "Recommendation": "Restrict storage SAS tokens to specific IP addresses/ranges where possible. Refer: https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-shared-access-signature-part-1. Note: In case the IP range is indeterminate (for instance, if the client is a PaaS endpoint), you may need to attest this control.",
      "Tags": [
        "SDL",
        "TCP",
        "Manual",
        "AuthZ",
        "StandardSku",
        "PremiumSku",
        "GeneralPurposeStorage",
        "BlobStorage",
        "PremiumFileShareStorage",
        "NetSec"
      ],
      "Enabled": true
    },
    {
      "ControlID": "Azure_Storage_AuthZ_Clients_Use_SAS",
      "Description": "End user/client apps should access Storage Account through SAS token only (and not via Storage Account Key)",
      "Id": "AzureStorage190",
      "ControlSeverity": "High",
      "Automated": "No",
      "MethodName": "",
      "Rationale": "A shared access signature (SAS) provides you with a way to grant limited access to objects in your Storage Account to other clients, without exposing your account key. This is in accordance with the principle of least privilege access.",
      "Recommendation": "Do not use Storage Account key directly in apps. Use a SAS token to limit the access based on scope, duration, IPs, etc. Refer: https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-shared-access-signature-part-1.",
      "Tags": [
        "SDL",
        "Best Practice",
        "Manual",
        "AuthZ",
        "StandardSku",
        "PremiumSku",
        "GeneralPurposeStorage",
        "BlobStorage",
        "PremiumFileShareStorage"
      ],
      "Enabled": true
    },
    {
      "ControlID": "Azure_Storage_DP_Rotate_Keys",
      "Description": "Storage Account keys must be rotated periodically",
      "Id": "AzureStorage200",
      "ControlSeverity": "Medium",
      "Automated": "No",
      "MethodName": "",
      "Rationale": "Periodic key/password rotation is a good security hygiene practice as, over time, it minimizes the likelihood of data loss/compromise which can arise from key theft/brute forcing/recovery attacks.",
      "Recommendation": "Rotate Storage Account keys on a periodic basis. To generated a new key, run command 'New-AzStorageAccountKey -KeyName '<key1/key2>' -Name '<StorageAccountName>' -ResourceGroupName '<RGName>'. Deploy the new key or derived SAS tokens to various clients as appropriate. Run 'Get-Help New-AzStorageAccountKey -full' for more help.",
      "Tags": [
        "SDL",
        "TCP",
        "Manual",
        "DP",
        "StandardSku",
        "PremiumSku",
        "GeneralPurposeStorage",
        "BlobStorage",
        "PremiumFileShareStorage"
      ],
      "Enabled": true
    },
    {
      "ControlID": "Azure_Storage_AuthZ_Allow_Limited_Access_to_Services",
      "Description": "Use Stored Access Policies with least privileges needed to access services in the Storage Account.",
      "Id": "AzureStorage210",
      "ControlSeverity": "High",
      "Automated": "No",
      "MethodName": "",
      "Rationale": "Granting minimum access ensures that users are granted just enough permissions to perform their tasks. This minimizes operations that can be performed on the resource in case of access policy key compromise.",
      "Recommendation": "Create a SAS token with Stored Access Policy for service access using the minimal required privileges. Refer: https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-shared-access-signature-part-1#controlling-a-sas-with-a-stored-access-policy.",
      "Tags": [
        "SDL",
        "TCP",
        "Manual",
        "AuthZ",
        "StandardSku",
        "PremiumSku",
        "GeneralPurposeStorage",
        "BlobStorage",
        "PremiumFileShareStorage"
      ],
      "Enabled": true
    },
    {
      "ControlID": "Azure_Storage_DP_Restrict_CORS_Access",
      "Description": "Ensure that CORS access is granted to a minimal set of trusted origins and only required verbs are supported.",
      "Id": "AzureStorage250",
      "ControlSeverity": "Medium",
      "Automated": "Yes",
      "MethodName": "CheckStorageCORSAllowed",
      "Rationale": "CORS enables applications running under one domain to access a resource under another domain. Using '*' (allow all) for CORS setting means that an application running under any domain can have access to your application's resources and data. Restricting allowed origins to the specific set that needs access aligns with the principle of least privilege.",
      "Recommendation": "Go to Azure Portal --> your Storage service --> Settings --> CORS --> for each of the Storage services i.e. Blob/File/Table/Queue --> Add --> Provide the specific domain names and other CORS details that should be allowed to make cross-origin calls. Note: No action is needed if you are not using CORS for your service.",
      "Tags": [
         "SDL",
         "TCP",
         "Automated",
         "DP",
         "StandardSku",
         "GeneralPurposeStorage",
         "BlobStorage",
         "OwnerAccess",
         "ResourceLocked"
      ],
      "Enabled": true
    },
    {
      "ControlID": "Azure_Storage_AuthZ_Restrict_Network_Access",
      "Description": "Ensure that Firewall and Virtual Network access is granted to a minimal set of trusted origins",
      "Id": "AzureStorage260",
      "ControlSeverity": "Medium",
      "Automated": "Yes",
      "MethodName": "CheckStorageNetworkAccess",
      "Rationale": "Restricting access using firewall/virtual network config reduces network exposure of a storage account by limiting access only to expected range/set of clients. Note that this depends on the overall service architecture and may not be possible to implement in all scenarios.",
      "Recommendation": "Go to Azure Portal --> your Storage service --> Settings --> Firewalls and virtual networks --> Selected Network. Provide the specific IP address and Virtual Network details that should be allowed to access storage account.",
      "Tags": [
        "SDL",
        "TCP",
        "Automated",
        "AuthZ",
        "StandardSku",
        "GeneralPurposeStorage",
        "BlobStorage",
        "PremiumSku",
        "NetSec"
      ],
      "Enabled": true
    },
    {
      "ControlID": "Azure_Storage_BCDR_Enable_Soft_Delete",
      "Description": "Soft delete should be enabled to allow recovery of deleted blobs or blob snapshots",
      "Id": "AzureStorage270",
      "ControlSeverity": "Medium",
      "Automated": "Yes",
      "MethodName": "CheckStorageSoftDelete",
      "Rationale": "Enabling soft delete feature on Storage acts as a safety measure to recover inadvertently or maliciously deleted blobs or blob snapshots. If your data is critical, this can be a valuable BC/DR mechanism.",
      "Recommendation": "Refer: https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-soft-delete to enable soft delete feature on Storage.",
      "Tags": [
        "SDL",
        "TCP",
        "Automated",
        "BCDR",
        "StandardSku",
        "PremiumSku",
        "GeneralPurposeStorage",
        "BlobStorage",
        "ResourceLocked",
        "OwnerAccess"
      ],
      "Enabled": true
   },
    {
      "ControlID": "Azure_Storage_AuthZ_Grant_Min_RBAC_Access",
      "Description": "All users/identities must be granted minimum required permissions using Role Based Access Control (RBAC)",
      "Id": "AzureStorage280",
      "ControlSeverity": "Medium",
      "Automated": "Yes",
      "MethodName": "CheckRBACAccess",
      "Rationale": "Granting minimum access by leveraging RBAC feature ensures that users are granted just enough permissions to perform their tasks. This minimizes exposure of the resources in case of user/service account compromise.",
      "Recommendation": "Remove any excessive privileges granted on the Search service. Run command: Remove-AzRoleAssignment -SignInName '<SignInName>' -Scope '<Scope>' RoleDefinitionName '<RoleDefinitionName>'. Run 'Get-Help Remove-AzRoleAssignment -full' for more help.",
      "Tags": [
        "SDL",
        "TCP",
        "Automated",
        "AuthZ",
        "RBAC",
        "BlobStorage",
        "StandardSku",
        "PremiumSku",
        "GeneralPurposeStorage"
      ],
      "Enabled": true
    },
    {
      "ControlID": "Azure_Storage_AuthN_Use_AAD_Based_Access",
      "Description": "Use AAD-based access for storage account",
      "Id": "AzureStorage290",
      "ControlSeverity": "Medium",
      "Automated": "Yes",
      "MethodName": "CheckStorageAADBasedAccess",
      "Rationale": "Where possible, use AAD-based identities (SPNs/groups/Users) to grant access to storage accounts using minimum RBAC roles. Wherever the client supports it, the SPN-type used should be a 'Managed Service Identity'(MSI). The identity is managed by the Azure platform and eliminates the need to provision/manage/rotate any secrets thus reducing the overall risk. Using the native enterprise directory for authentication ensures that there is a built-in high level of assurance in the user identity established for subsequent access control.",
      "Recommendation": "Refer: https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview, https://docs.microsoft.com/en-us/azure/storage/common/storage-auth-aad-msi ",
      "Tags": [
        "SDL",
        "TCP",
        "Automated",
        "AuthN",
        "StandardSku",
        "PremiumSku",
        "GeneralPurposeStorage",
        "BlobStorage"
      ],
      "Enabled": true
    }
 
  ]
}