Last Updated: 2020-11-12 10:11:42 UTC
by Daniel Wesemann (Version: 1)
In the previous diary, I explained the three public access levels of Azure Blob Storage, and how to investigate the setup for any issues. Until a couple of months ago, there was no reliable way to prevent the problem from occurring in the first place, but thankfully, Microsoft has finally seen the light.
At the level of the Storage Account, there is now a new setting "Allow Blob Public Access", which can be set to "Disabled".
Once disabled, the access level set on the containers within this storage account no longer matters, public unauthenticated access will always be denied:
This adds a welcome additional safety net, because the Containers within this storage account cannot be set to "public access" anymore, not even by mistake:
Even better, there is now also a "preview" rule available for this setting in Azure Policies. Go to Policies -> Definitions, then search for "Public", to find the Policy Definition named "[Preview]: Storage account public access should be disallowed".
Click on it, select "Assign", and push it to a scope of your choice. Set the parameter to "Deny", and once the policy is active, new storage accounts can only be created in your tenant or subscription if they have public access turned off. If the corresponding setting ("Allow Blob Public Access") under the "Advanced" tab of the "Create storage account" dialog is not set to "disabled", all new storage account creation attempts will fail.
Refer to https://docs.microsoft.com/en-us/azure/storage/blobs/anonymous-read-access-prevent and https://docs.microsoft.com/en-us/azure/storage/blobs/anonymous-read-access-configure for more information, how to audit for issues before pushing a "deny" rule, and any other possible side effects. But once you have this resolved and rolled out as a "deny" policy for your Azure subscription or tenant, you'll sleep better, knowing that you significantly reduced the likelyhood of accidential data breaches via exposed storage accounts in your environment.
Last Updated: 2020-11-12 00:22:38 UTC
by Daniel Wesemann (Version: 1)
With the headline "Improperly Configured AWS S3 Bucket Exposes 10 Million Hotel Guest Records" in this week's SANS NewsBites, I wanted to shed a little light on the same problem, but in Azure.
Microsoft Azure Blob Storage is very similar to AWS S3, and comes in three access control flavors:
- "Private" is thankfully the default. and turns off anonymous public access
- "Blob" allows unauthenticated public access to a file, as long as you know its name
- "Container" is the same as blob, but also allows to list the folder contents
You can check the configured access level by looking at your Azure resources, clicking on the storage accounts, and then drilling down into the storage containers present:
An access level of "Blob" can be sufficient for something like a public website. It behaves very similar to a web server - if someone knows or can guess the file name, they can access the file, no questions asked. For business data, this level of access is dangerous though, because its "security" basically just relies on your assumption that nobody else knows or can guess the file name. More often than not, this assumption turns out to be ill-advised. Other files that you intentionally share publicly might have a similar naming structure, or you maybe are using easily guessable names to begin with. In a nutshell: If you would consider a file too sensitive to store on your public web server, don't store it in a Azure container with "Blob" access, either.
An access level of "Container" is the same as "Blob", but worse. An attacker just needs to know the name of the Storage Account itself. That's the part of the name in front of the *.blob.core.windows.net URLs that you certainly have encountered before. That name space is pretty small, because the Storage Account Name has to be unique across all Azure tenants (Microsoft Azure Customers). While creating a new storage account, "name collisions" are therefore quite frequent:
The container name itself (one level below the storage account) only needs to be unique per storage account though, and cannot be directly enumerated. Therefore, even accounts that are exposed at access level "Container" retain a tiny modicum of security-by-obscurity, presumed that your container is indeed named obscurely. In my example shown, the container is named "logs", and would likely be discovered real quick once someone develops any interest in my "temporaryexampleonly" container. Enumerating the contents is then only one API call away, and the resulting XML/JSON is readily machine parseable to extract the URLs of all the files in the container. Once the file and path names are known, the files can be obtained even if the access level is later changed back to "Blob".
One way to quickly find out if you have exposed Containers in your Azure Storage setup is to use Azure Security Center (ASC). Even at the "Free" tier, you will see recommendations like these:
If your ASC displays this recommendation for any of your storage accounts, take it seriously, and investigate if the flagged resource is public-by-design, or public-by-mistake.
In the next diary, I'm going to show how you can reliably prevent the problem from occurring in the first place.