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"
      }
   },
    {
      "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 'Add-AzMetricAlertRule -MetricName 'AnonymousSuccess' -Operator 'GreaterThan' -Threshold '<Threshold count>' -TimeAggregationOperator 'Total' -WindowSize '<Duration window>' -Action '<New-AzAlertRuleEmail -SendToServiceOwner>' -Name '<AlertName>' -ResourceGroup '<RGName>' -TargetResourceId '<TargetResourceId>' -Location '<Location>''. TargetResourceId format is '<StorageResourceId>/services/<blob/file/queue/table>'. Run 'Get-Help Add-AzMetricAlertRule -full' for more help. Note: You will need to enable this for all service types within Storage (Blob, File, Table, Queue, etc.) even if you are only using one of them.",
      "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"
      ],
      "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
    }
 
  ]
}