With the findings announced by Wiz around the ChaosDB vulnerability, the Cloudrail team thought a lot about how this impacted current customers. Thanks to the quick response by the Azure team, the ChaosDB vulnerability is no longer a concern, but we asked ourselves, “How could we avoid these vulnerabilities in the first place?”.

Cloudrail believes strongly in continuous security through GitOps – iteratively improving the state of your cloud security by validating requirements and infrastructure as code. We also believe in implementing continuous security as gracefully as possible. With that said, here are ten actionable steps we recommend completing to secure your Cosmos DB instance, and how you can implement them gracefully with Indeni Cloudrail.

1. Ensure Azure Cosmos DB has Public Network Access disabled

Disabling public network access for a CosmosDB account has immediate benefits. However, it isn’t always that easy to disable access as you may have 3rd party tools that require access to the Cosmos DB data. In some cases, this might even be a false positive for DB instances that are intentionally set to be publicly exposed. We’ll go over how you can gracefully introduce this security requirement for future development below.

2. Ensure Azure Cosmos DB accounts are only accessible via private link

We consider this requirement as a follow-up to the prior. This step is mainly important for CosmosDB environments where data needs to be accessible remotely.

3. Turn On Advanced Threat Protection

Azure’s Advanced Threat Protection, when enabled, can be configured to notify you if your CosmosDB instances are accessed from abnormal locations. Making sure this is enabled for any future Cosmos DB instances is a no-brainer.

4. Restrict access to Cosmos DB accounts

Similar to the first step, there may be limited capacity within your organization to strongly enforce this. We will show you how to gracefully introduce this security requirement into your organization.

5. Use system-assigned managed identities for Azure Cosmos DB accounts

The effective remediation step to address the ChaosDB issue was to rotate your keys. Instead of having to regularly rotate keys, utilizing system-assigned managed identities helps organizations maintain service continuity while not being pinned down to a particular API key. Again, this is somewhat situational as existing services may be already using existing keys, so we recommend that, at minimum, new Cosmos DB instances should always be required to be accessed through system-managed identities.

6. Ensure Azure Cosmos DB accounts use customer-managed keys to encrypt data at rest

Customer-managed keys are recommended to be used to encrypt data at rest for any datastore. There are plenty of options available for managing your CMKs, but this requirement should be strongly enforced. For existing Cosmos DB instances, this is somewhat harder to implement as it does require actively migrating the data in your existing Cosmos DB instance to a new one with encryption enabled. We recommend that you mandate this requirement only on new Cosmos DB instances.

7. Ensure Azure Cosmos DB accounts have tags

While this does not have an immediate security benefit, tags are mostly valuable as metadata references when reviewing security events. Tagging ensures that your security team can properly identify assets. Tag conventions are typically unique per organization. We recommend that you create a custom policy-as-code to ensure that all Cosmos DB instances use the right tags as guided by your organization’s policy.

8. Ensure Azure Cosmos DB private endpoints have logging enabled

Ensuring that your private endpoints have logging enabled ensures that you can appropriately trace all access activities with external services.

9. Ensure Azure Cosmos DB accounts have diagnostic logs enabled

While this is at the bottom of our list, we highly recommend enabling this. It should be mandatory in all CosmosDB instances as diagnostic logs enable even the simplest investigative operations necessary to identify malicious activity.

10. Implement Cloudrail to introduce continuous security gracefully

As you can tell, we cautiously recommend enforcing the above requirements due to the potential overhaul needed to update the existing infrastructure. Using cloudrail we’re able to gracefully introduce continuous security and changes.

Gracefully Introducing These Changes With Cloudrail

In our sample terraform config below, we’ll simulate a real life example. One Cosmos DB account has already been deployed – the other has not. We’ll take advantage of Cloudrail’s Mandate New Resource enforcement level, allowing us to enforce security requirements only for resources that have not yet been deployed.

This first template represents an already-existing resource with a vulnerable Cosmos DB account (public network access is enabled). It has already been deployed.

resource "azurerm_resource_group" "rg" {
 name     = "cloudrailtest-rg"
 location = "West Europe"
}
 
resource "random_integer" "ri" {
 min = 10000
 max = 99999
}
 
resource "azurerm_cosmosdb_account" "db" {
 name                          = "cloudrail-test-cosmos-db-${random_integer.ri.result}"
 location                      = azurerm_resource_group.rg.location
 resource_group_name           = azurerm_resource_group.rg.name
 offer_type                    = "Standard"
 kind                          = "GlobalDocumentDB"
 enable_automatic_failover     = true
 public_network_access_enabled = true
 
 consistency_policy {
   consistency_level       = "BoundedStaleness"
   max_interval_in_seconds = 400
   max_staleness_prefix    = 200000
 }

The template is then updated to add another Cosmos DB account (db2), with the same vulnerability, that is yet to be created.

resource "azurerm_resource_group" "rg" {
 name     = "cloudrailtest2-rg"
 location = "West Europe"
}
 
resource "random_integer" "ri" {
 min = 10000
 max = 99999
}
 
resource "azurerm_cosmosdb_account" "db" {
 name                          = "cloudrail-test-cosmos-db-${random_integer.ri.result}"
 location                      = azurerm_resource_group.rg.location
 resource_group_name           = azurerm_resource_group.rg.name
 offer_type                    = "Standard"
 kind                          = "GlobalDocumentDB"
 enable_automatic_failover     = true
 public_network_access_enabled = true
 
 consistency_policy {
   consistency_level       = "BoundedStaleness"
   max_interval_in_seconds = 400
   max_staleness_prefix    = 200000
 }
 
 geo_location {
   location          = azurerm_resource_group.rg.location
   failover_priority = 0
 }
 
 geo_location {
   location          = "France Central"
   failover_priority = 1
 }
}
 
resource "azurerm_cosmosdb_account" "db2" {
 name                          = "cloudrail-test-cosmos-db2-${random_integer.ri.result}"
 location                      = azurerm_resource_group.rg.location
 resource_group_name           = azurerm_resource_group.rg.name
 offer_type                    = "Standard"
 kind                          = "GlobalDocumentDB"
 enable_automatic_failover     = true
 public_network_access_enabled = true
 
 consistency_policy {
   consistency_level       = "BoundedStaleness"
   max_interval_in_seconds = 400
   max_staleness_prefix    = 200000
 }
 
 geo_location {
   location          = azurerm_resource_group.rg.location
   failover_priority = 0
 }
 
 geo_location {
   location          = "France Central"
   failover_priority = 1
 }
}

We will then set our enforcement level in the Cloudrail web app to “Mandate New Resources Only”, which will only flag security vulnerabilities in newly created resources.

Now, we’ll run Cloudrail to assess our infrastructure. As indicated by the “Mandate New Resources Only” enforcement level, Cloudrail only flags the new Cosmos DB account (db2), not the one that has already been created.

Using the Mandate New Resources Only enforcement level, you can use Cloudrail to start securing your cloud today without affecting your currently running infrastructure. By introducing things gracefully, we can begin to answer the question “How could we avoid vulnerabilities in the first place?”.

Looking to get started with Cloudrail? It’s free! Check out cloudrail.app to get started.