Storage

Storage accounts play an important part in the overall solution architecture. Storage accounts can store important information, such as user PII data, business transactions, data, and more. It is of utmost importance that storage accounts are secure and only allow access to authorized users. The data stored is encrypted and transmitted using secure channels. The storage, as well as the users and client applications consuming the storage account and its data, play a crucial role in the overall security of the data. They should also keep data encrypted at all times. This also includes credentials and connection strings connecting to data stores.

Azure provides Role Based Access Control (RBAC) to govern who can manage Azure storage accounts. These RBAC permissions are allowed to users and groups in Azure Active Directory (AD). However, when an application to be deployed on Azure is created, it will have users and customers that are not available in Azure AD. To allow users to access the storage account, Azure Storage provides storage access keys. There are two types of access keys at the storage account level—primary and secondary. Users possessing these keys can connect to the storage account. These storage access keys are used in the authentication step when accessing the storage account. Applications can access storage accounts using either primary or secondary keys. Two keys are provided so that if the primary key is compromised, applications can be updated to use the secondary key, while the primary key is regenerated. This helps minimize application downtime. Moreover, it provides and enhances security by removing the compromised key without impacting applications. The Storage key details, as seen on the Azure Portal, as shown in the following screenshot:

Azure Storage provides four services—blob, files, queues, and tables—in an account. Each of these services also provides infrastructure for securing themselves using secure access tokens. A shared access signature (SAS) is a URI that grants restricted access rights to Azure storage services: blob, files, queues, and tables. These SAS token can be shared with clients who should not be trusted with the entire storage account key to constrain access to certain storage account resources. By distributing a SAS URI to these clients, access to resources is granted for a specified period.

SAS tokens exist at both the storage account and the individual blob, file, table, and queue levels. A storage account-level signature is more powerful and has the right to allow and deny permissions at the individual service level. It can also be used instead of individual resource service levels:

Generating and sharing SAS tokens is preferable to sharing storage account keys. SAS tokens provide granular access to resources and can be combined together as well. These tokens include read, write, delete, list, add, create, update, and process. Moreover, even access to resources can be determined while generating SAS tokens. It could be for blobs, tables, queues, and files individually, or a combination of them. Storage account keys are for the entire account and cannot be constrained for individual services. Neither can they be constrained from the permissions perspective. It is much easier to create and revoke SAS tokens than it is for storage access keys. SAS tokens can be created for use for a certain period of time, after which they become invalid automatically.

It is to be noted that if storage account keys are regenerated, then the SAS token based on them will become invalid and a newer SAS token should be created and shared with clients.

Cookie stealing, script injection, and denial of service attacks are common means used by attackers to disrupt an environment and steal data. Browsers and the HTTP protocol implement a built-in mechanism that ensures that these malicious activities cannot be performed. Generally, anything that is cross-domain is not allowed by either HTTP or browsers. A script running in one domain cannot ask for resources from another domain. However, there are valid use cases where such requests should be allowed. The HTTP protocol implements Cross Origin Resource Sharing (CORS). With the help of CORS, it is possible to access resources across domains and make them work. Azure Storage configures CORS rules for blobs, file, queue, and table resources. Azure Storage allows the creation of rules that are evaluated for each authenticated request. If the rules are satisfied, the request is allowed to access the resource.

Data must not only be protected while in transit; it should also be protected while at rest as well. If data at rest is not encrypted, anybody who has access to the physical drive in the data center can read the data. Although the possibility is negligible, customers still should encrypt their data. Storage service encryption also helps protect data at rest. This service works transparently and injects itself without users knowing about it. It encrypts data when the data is saved in a storage account, and decrypts it automatically when it is read. This entire process happens without users performing any additional activity.

Azure account keys must be rotated periodically. This will ensure that an attacker is not able to breach access to storage accounts.

It is also a good idea to regenerate the keys; however, this must be evaluated in regard to its usage in existing applications. If it breaks the existing application, these applications should be prioritized for change management, and changes should be applied gradually.

As much as possible, individual service-level SAS tokens with a limited timeframe should be generated and provided to users who should access the resources. Permissions must be evaluated and optimum permissions must be provided.

SAS keys and storage account keys should be stored in an Azure Key Vault. This provides security storage and access to them. These keys can be read at runtime by applications from the key vault, instead of storing them in configuration files.