include::../../../shared_content/secrets/description.adoc[]

== Why is this an issue?

include::../../../shared_content/secrets/rationale.adoc[]

=== What is the potential impact?

Azure Storage Account Keys are used to authenticate and authorize access to
Azure Storage resources, such as blobs, queues, tables, and files. These keys
are used to authenticate requests made against the storage account.

If an Azure Storage Account Key is leaked to an unintended audience, it can pose
a significant security risk to your Azure Storage account.

An attacker with access to your storage account key can potentially access and
modify all the data stored in your storage account. They can also create new
resources, delete existing ones, and perform other actions that can compromise
the integrity and confidentiality of your data.

In addition, an attacker with access to your storage account key can also incur
charges on your account by creating and using resources, which can result in
unexpected billing charges.

== How to fix it

include::../../../shared_content/secrets/fix/revoke.adoc[]

include::../../../shared_content/secrets/fix/recent_use.adoc[]

include::../../../shared_content/secrets/fix/vault.adoc[]

=== Code examples

==== Noncompliant code example

[source,csharp,diff-id=1,diff-type=noncompliant]
----
using Azure.Storage.Blobs;
using Azure.Storage;

class Example
{
    static void Main(string[] args)
    {
        string account = "accountname";
        string accountKey = "4dVw+l0W8My+FwuZ08dWXn+gHxcmBtS7esLAQSrm6/Om3jeyUKKGMkfAh38kWZlItThQYsg31v23A0w/uVP4pg=="; // Noncompliant
        StorageSharedKeyCredential sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);

        BlobServiceClient blobServiceClient = new BlobServiceClient(
            new Uri($"https://{account}.blob.core.windows.net"),
            sharedKeyCredential);
    }
}
----

==== Compliant solution

Using environment variables:

[source,csharp,diff-id=1,diff-type=compliant]
----
using System;
using Azure.Storage.Blobs;
using Azure.Storage;

class Example
{
    static void Main(string[] args)
    {
        string account = Environment.GetEnvironmentVariable("ACCOUNT_NAME");
        string accountKey = Environment.GetEnvironmentVariable("ACCOUNT_KEY");
        StorageSharedKeyCredential sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);

        BlobServiceClient blobServiceClient = new BlobServiceClient(
            new Uri($"https://{account}.blob.core.windows.net"),
            sharedKeyCredential);
    }
}
----

Using a passwordless approach, thanks to https://learn.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-dotnet?tabs=visual-studio%2Cmanaged-identity%2Croles-azure-portal%2Csign-in-azure-cli%2Cidentity-visual-studio#sign-in-and-connect-your-app-code-to-azure-using-defaultazurecredential[DefaultAzureCredential]:

[source,csharp]
----
using System;
using Azure.Storage.Blobs;
using Azure.Identity;

class Example
{
    static void Main(string[] args)
    {
        string account = Environment.GetEnvironmentVariable("ACCOUNT_NAME");
        var blobServiceClient = new BlobServiceClient(
                new Uri($"https://{account}.blob.core.windows.net"),
                new DefaultAzureCredential());
    }
}
----

//=== How does this work?

//=== Pitfalls

//=== Going the extra mile

== Resources

include::../../../shared_content/secrets/resources/standards.adoc[]

=== Documentation

* Microsoft Documentation - https://docs.microsoft.com/en-us/azure/storage/common/storage-account-keys-manage?tabs=azure-portal[Manage storage account access keys]

//=== Benchmarks
