Api Key Exposure on Azure
How Api Key Exposure Manifests in Azure
API key exposure in Azure environments typically occurs through several Azure-specific patterns. The most common scenario involves Azure Function keys being inadvertently exposed through HTTP triggers. By default, Azure Functions create two types of keys: function keys (scoped to individual functions) and host keys (scoped to the entire function app). When developers use the [SystemTrigger] attribute with AuthorizationLevel.Anonymous, anyone with the function URL can execute it without authentication.
// Vulnerable Azure Function - API key not required
[FunctionName("ProcessData")]
public static async Task<HttpResponseData> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequestData req,
FunctionExecutionContext context)
{
// No API key validation - anyone can call this
var data = await req.ReadFromJsonAsync<MyData>();
return req.CreateResponse(HttpStatusCode.OK);
}
Another Azure-specific exposure pattern occurs in Azure API Management where developers accidentally publish APIs with subscription keys disabled. When creating an API operation in API Management, the Subscription Required setting defaults to True, but developers sometimes disable it for testing and forget to re-enable it.
// Azure API Management operation with subscription key disabled
var operation = new OpenApiOperation
{
Description = "Get user data",
Responses = new OpenApiResponses
{
["200"] = new OpenApiResponse { Description = "Success" }
}
};
// This line would be missing or set to false
operation.SetSubscriptionKeyRequired(true); // Should be true, but often forgotten
Azure App Configuration is another common source of API key exposure. Developers frequently hardcode connection strings or access keys in application code rather than using Azure Key Vault or managed identities.
// Vulnerable - hardcoded App Configuration connection string
var config = new ConfigurationBuilder()
.AddAzureAppConfiguration("Endpoint=https://myconfig.azconfig.io;Id=abc123;Secret=xyz789")
.Build();
Azure Service Bus and Event Grid topics also suffer from key exposure when developers use shared access signatures (SAS) keys directly in client applications instead of implementing proper service-to-service authentication.
Azure-Specific Detection
Detecting API key exposure in Azure requires both static code analysis and runtime scanning. For static analysis, Azure DevOps and GitHub Actions can integrate security scanning tools that specifically look for Azure SDK patterns. The middleBrick CLI tool excels at detecting these issues by scanning Azure endpoints without requiring credentials.
# Scan Azure Function endpoints for API key exposure
middlebrick scan https://myazurefunction.azurewebsites.net/api/ProcessData
# Scan Azure API Management endpoints
middlebrick scan https://myapim.azure-api.net/users/get
# Scan Azure App Configuration endpoints
middlebrick scan https://myconfig.azconfig.io
middleBrick's Azure-specific detection includes checking for:
- Azure Function endpoints with
AuthorizationLevel.AnonymousorAuthorizationLevel.Functionwithout proper key validation - Azure API Management operations with subscription keys disabled
- Azure App Configuration endpoints accessible without authentication
- Azure Service Bus namespaces with overly permissive SAS policies
- Azure Event Grid topics with shared access keys exposed
The tool performs active probing to test whether endpoints accept unauthenticated requests, simulating real attack scenarios. For Azure Functions, it attempts to invoke functions without providing any function keys, checking if the function still executes.
Azure Security Center and Defender for Cloud also provide detection capabilities, but they require Azure-native integration and credentials. middleBrick's black-box approach means you can scan any Azure endpoint without configuration, making it ideal for testing third-party Azure services or pre-production environments where you don't have credentials.
For comprehensive Azure security, combine middleBrick scanning with Azure Policy to enforce security standards across your Azure subscriptions. Azure Policy can prevent the deployment of resources with insecure configurations, while middleBrick can detect existing exposures.
Azure-Specific Remediation
Remediating API key exposure in Azure requires implementing Azure's native security features. For Azure Functions, always use AuthorizationLevel.Function or AuthorizationLevel.Admin instead of Anonymous. Additionally, implement Azure Active Directory authentication for enhanced security.
// Secure Azure Function - requires function key
[FunctionName("ProcessData")]
public static async Task<HttpResponseData> Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestData req,
FunctionExecutionContext context)
{
// Function key required - unauthorized requests are rejected
var data = await req.ReadFromJsonAsync<MyData>();
return req.CreateResponse(HttpStatusCode.OK);
}
// Even better - use Azure AD authentication
[FunctionName("ProcessDataSecure")]
public static async Task<HttpResponseData> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequestData req,
FunctionExecutionContext context,
FunctionContext executionContext)
{
var principal = executionContext.GetHttpContext().User;
if (!principal.Identity.IsAuthenticated)
{
return req.CreateResponse(HttpStatusCode.Unauthorized);
}
// Process authenticated request
var data = await req.ReadFromJsonAsync<MyData>();
return req.CreateResponse(HttpStatusCode.OK);
}
For Azure API Management, ensure all operations have subscription keys enabled and implement proper rate limiting and quotas.
// Configure Azure API Management with subscription keys
var operationPolicy = new OpenApiOperationPolicy
{
Policy = @"
<policies>
<inbound>
<validate-jwt header-name="Authorization" failed-validation-httpcode="401"
failed-validation-error-message="Unauthorized">
<openid-config url="https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration" />
<required-claims>
<claim name="aud" match="any" separator=",">
<value>your-api-audience</value>
</claim>
</required-claims>
</validate-jwt>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
"
};
Azure Key Vault should be used for all secrets and connection strings. The middleBrick CLI can verify that your applications properly use Key Vault rather than hardcoded credentials.
// Secure - using Azure Key Vault
var keyVaultEndpoint = new Uri(Environment.GetEnvironmentVariable("KEY_VAULT_URI"));
var credential = new DefaultAzureCredential();
var client = new SecretClient(keyVaultEndpoint, credential);
// Retrieve secrets at runtime, never hardcode
var connectionString = await client.GetSecretAsync("AppConfigConnectionString");
var config = new ConfigurationBuilder()
.AddAzureAppConfiguration(connectionString.Value.Value)
.Build();
For Azure Service Bus and Event Grid, use managed identities instead of SAS keys whenever possible. This eliminates the need to manage and rotate keys.
// Secure - using managed identity
var credential = new DefaultAzureCredential();
var serviceBusClient = new ServiceBusClient("fully-qualified-namespace", credential);
var sender = serviceBusClient.CreateSender("queue-name");
Frequently Asked Questions
How can I scan my Azure Functions for API key exposure without modifying my code?
middleBrick's black-box scanning approach allows you to scan Azure Functions without any code changes or credentials. Simply provide the function URL to the middleBrick CLI or web dashboard. The scanner will test whether the function accepts unauthenticated requests and check for common Azure-specific vulnerabilities like exposed function keys or overly permissive authorization levels.
What's the difference between Azure Function keys and API Management subscription keys?
Azure Function keys are scoped to individual functions or function apps and provide basic authentication for HTTP-triggered functions. API Management subscription keys are more comprehensive, providing access control, rate limiting, and usage analytics across multiple APIs. middleBrick tests both types by attempting to access endpoints without providing any keys, helping you identify when these security mechanisms are improperly configured or disabled.