HIGH token leakageazure

Token Leakage on Azure

How Token Leakage Manifests in Azure

Token leakage in Azure environments typically occurs through misconfigured Azure services, exposed storage accounts, and improper handling of authentication tokens in client-side code. Azure's extensive ecosystem creates multiple attack surfaces where tokens can be inadvertently exposed.

The most common manifestation is through Azure Blob Storage misconfigurations. When storage accounts are set to public access or when SAS (Shared Access Signature) tokens are generated with overly permissive scopes, attackers can enumerate and access sensitive data. Consider this vulnerable pattern:

const azure = require('azure-storage');
const blobService = azure.createBlobService('accountName', 'accountKey');

// Vulnerable: SAS token generation with excessive permissions
const sasToken = blobService.generateSharedAccessSignature(
  'mycontainer',
  { 
    AccessPolicy: { 
      Permissions: azure.BlobUtilities.SharedAccessPermissions.READ | 
                   azure.BlobUtilities.SharedAccessPermissions.WRITE | 
                   azure.BlobUtilities.SharedAccessPermissions.DELETE,
      Start: new Date(),
      Expiry: new Date(new Date().valueOf() + 24 * 60 * 60 * 1000) // 24 hours
    }
  }
);

// Token leakage: SAS token returned in API response
app.get('/get-sas-token', (req, res) => {
  res.json({ sasToken }); // Exposes token to client
});

Another Azure-specific scenario involves Azure Key Vault misconfigurations. When Key Vault access policies grant excessive permissions or when secrets are stored in plain text, tokens and credentials can be compromised:

const msRestAzure = require('ms-rest-azure');
const KeyVault = require('azure-keyvault');

// Vulnerable: Service principal credentials hardcoded
const clientId = 'your-client-id';
const clientSecret = 'your-client-secret'; // Token leakage risk
const domain = 'your-domain';

msRestAzure.loginWithServicePrincipalSecret(clientId, clientSecret, domain, (err, credentials) => {
  if (err) throw err;
  
  const keyVaultClient = new KeyVault.KeyVaultClient(credentials);
  keyVaultClient.getSecret('https://mykeyvault.vault.azure.net/secrets/mysecret', '', (err, result) => {
    console.log(result); // Secret value exposed in logs
  });
});

Azure Functions present unique token leakage risks through improper HTTP trigger configurations. When functions are not properly secured, they can expose tokens through HTTP responses or logs:

module.exports = async function (context, req) {
  const token = req.headers['authorization']; // Token captured but not validated
  
  // Vulnerable: Token logged without sanitization
  context.log(`Received token: ${token}`); // Token leakage in logs
  
  // Vulnerable: Token returned in response
  context.res = {
    body: { token: token } // Direct token exposure
  };
};

Azure App Service token leakage often occurs through application settings exposure. When configuration files containing tokens are accidentally committed to repositories or when App Service configurations are not properly secured:

# Azure CLI: Insecure token storage
az webapp config appsettings set \
  --name myapp \
  --resource-group mygroup \
  --settings \
    STORAGE_ACCOUNT_KEY="my-storage-key" \
    DATABASE_PASSWORD="my-db-password" # Tokens stored in plain text

Azure-Specific Detection

Detecting token leakage in Azure environments requires a multi-layered approach combining Azure-native tools with specialized scanning capabilities. Azure Security Center provides baseline monitoring, but it lacks the depth needed for comprehensive token leakage detection.

Azure Security Center can identify some token-related misconfigurations through its security policies. You can enable specific policies to detect overly permissive SAS tokens and public storage access:

# Enable Azure Policy to detect public storage accounts
az policy assignment create \
  --name "DenyPublicStorage" \
  --display-name "Deny Public Storage Access" \
  --policy "https://raw.githubusercontent.com/Azure/azure-policy/master/samples/Storage/storage-account-public-access/DenyPublicStorageAccess.json"

# Enable diagnostic logging to detect token leakage in logs
az monitor diagnostic-settings create \
  --resource-group myResourceGroup \
  --name "TokenLeakageDetection" \
  --resource myStorageAccount \
  --logs '[{"category": "StorageRead", "enabled": true}, {"category": "StorageWrite", "enabled": true}]' \
  --workspace /subscriptions/my-subscription/resourcegroups/my-workspace/providers/microsoft.operationalinsights/workspaces/my-log-analytics

For comprehensive detection, middleBrick's Azure-specific scanning capabilities provide deep analysis of token leakage vulnerabilities. The scanner examines Azure-specific attack patterns including SAS token enumeration, Key Vault misconfigurations, and Azure Functions security flaws:

# Scan Azure API endpoints with middleBrick
middlebrick scan https://myazureapi.azurewebsites.net \
  --output json \
  --include azure-storage,azure-keyvault,azure-functions

# GitHub Action for continuous Azure security monitoring
name: Azure Security Scan
on: [push, pull_request]

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run middleBrick Azure Scan
        run: |
          npm install -g middlebrick
          middlebrick scan https://myazureapi.azurewebsites.net --output json > security-report.json
      - name: Fail on high-risk findings
        run: |
          SCORE=$(jq '.overall_score' security-report.json)
          if [ $SCORE -lt 80 ]; then
            echo "Security score below threshold: $SCORE"
            exit 1
          fi

Azure Application Insights can be configured to detect token patterns in telemetry data. By creating custom log queries, you can identify potential token leakage:

// Kusto query to detect token patterns in Azure logs
let tokenPatterns = dynamic([
  @"Bearer [A-Za-z0-9-_.]{10,}",
  @"Basic [A-Za-z0-9+/=]{10,}",
  @"sk=[A-Za-z0-9-_.]{10,}",
  @"sig=[A-Za-z0-9-_.]{10,}"
]);

traces
| where message has_any (tokenPatterns)
| summarize count() by cloud_RoleName, bin(timestamp, 1h)
| where count_ > 5 // Multiple token detections in an hour
| project timestamp, cloud_RoleName, count_, message

Azure-Specific Remediation

Remediating token leakage in Azure requires implementing Azure-native security controls and following Azure's security best practices. The key is to eliminate token exposure while maintaining functionality.

For Azure Blob Storage, implement managed identities and Azure AD authentication instead of SAS tokens:

const { BlobServiceClient } = require('@azure/storage-blob');
const { DefaultAzureCredential } = require('@azure/identity');

// Secure: Using managed identity instead of SAS tokens
const blobServiceClient = new BlobServiceClient(
  `https://${process.env.AZURE_STORAGE_ACCOUNT_NAME}.blob.core.windows.net`,
  new DefaultAzureCredential()
);

// Secure: Scoped access without token exposure
async function uploadFile(containerName, blobName, filePath) {
  const containerClient = blobServiceClient.getContainerClient(containerName);
  const blockBlobClient = containerClient.getBlockBlobClient(blobName);
  
  const uploadResponse = await blockBlobClient.uploadFile(filePath, {
    onProgress: (event) => {
      console.log(`Uploaded ${event.loadedBytes} bytes`);
    }
  });
  
  return uploadResponse.requestId;
}

// Secure: Token never exposed to client
app.get('/upload-url', async (req, res) => {
  try {
    const containerClient = blobServiceClient.getContainerClient('uploads');
    const blobName = `${Date.now()}-${req.query.filename}`;
    const blockBlobClient = containerClient.getBlockBlobClient(blobName);
    
    // Generate upload URL without exposing tokens
    const uploadUrl = await blockBlobClient.generateBlobUploadUrl();
    res.json({ uploadUrl: uploadUrl.url });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

For Azure Key Vault, implement the principle of least privilege and use Azure AD authentication:

const { DefaultAzureCredential } = require('@azure/identity');
const { KeyVaultSecretClient } = require('@azure/keyvault-secrets');

// Secure: Managed identity with least privilege
const credential = new DefaultAzureCredential();
const vaultUrl = `https://${process.env.KEY_VAULT_NAME}.vault.azure.net`;
const client = new KeyVaultSecretClient(vaultUrl, credential);

// Secure: No token exposure in code
async function getSecret(secretName) {
  try {
    const secret = await client.getSecret(secretName);
    return secret.value; // Value returned, not the token
  } catch (error) {
    console.error(`Error retrieving secret: ${error.message}`);
    throw error;
  }
}

// Secure: Azure RBAC for access control
// In Azure CLI or Portal:
az role assignment create \
  --assignee my-managed-identity \
  --role "Key Vault Secrets User" \
  --scope /subscriptions/my-subscription/resourceGroups/my-group/providers/Microsoft.KeyVault/vaults/my-key-vault

For Azure Functions, implement Azure AD authentication and secure HTTP triggers:

const { AppServiceTokenStore } = require('@azure/identity');

// Secure: Azure AD authentication for function
module.exports = async function (context, req) {
  const credential = new AppServiceTokenStore();
  
  try {
    // Validate token before processing
    const token = await credential.getToken('https://management.azure.com/.default');
    if (!token) {
      context.res = {
        status: 401,
        body: 'Unauthorized'
      };
      return;
    }
    
    // Process request securely
    context.res = {
      body: { message: 'Request processed securely' }
    };
  } catch (error) {
    context.log.error('Authentication error:', error.message);
    context.res = {
      status: 500,
      body: 'Internal server error'
    };
  }
};

Azure App Service configurations should use Key Vault references instead of plain text settings:

# Secure: Key Vault references instead of plain text
az webapp config appsettings set \
  --name myapp \
  --resource-group mygroup \
  --settings \
    [email protected](SecretUri=https://mykeyvault.vault.azure.net/secrets/storage-key) \
    [email protected](SecretUri=https://mykeyvault.vault.azure.net/secrets/db-password)

# Secure: Managed identity for App Service
az webapp identity assign \
  --resource-group mygroup \
  --name myapp \
  --role "Key Vault Secrets User" \
  --scope /subscriptions/my-subscription/resourceGroups/mygroup/providers/Microsoft.KeyVault/vaults/mykeyvault

Frequently Asked Questions

How does Azure's managed identity feature prevent token leakage?
Azure Managed Identity eliminates the need to store credentials in code or configuration files. Instead of handling tokens directly, your application authenticates with Azure AD using the system-assigned or user-assigned identity. The identity is automatically managed by Azure, and tokens are obtained through secure channels without exposing them to your application code. This removes the risk of accidentally logging tokens or returning them in API responses, as the identity handles authentication transparently.
Can middleBrick detect Azure-specific token leakage patterns?
Yes, middleBrick includes Azure-specific security checks that scan for token leakage patterns unique to Azure services. The scanner examines Azure Blob Storage configurations for overly permissive SAS tokens, analyzes Azure Functions for insecure HTTP trigger configurations, checks Azure App Service settings for exposed credentials, and validates Key Vault access policies. middleBrick's Azure scanning module tests 12 security categories including Authentication, BOLA/IDOR, and Input Validation, providing a security score (0-100) with prioritized findings and remediation guidance specific to Azure's ecosystem.