HIGH auth bypassazure

Auth Bypass on Azure

How Auth Bypass Manifests in Azure

Auth bypass in Azure environments often exploits the platform's complex identity and access management (IAM) layers. One common pattern involves token manipulation where attackers intercept and modify JWT claims to escalate privileges. Azure AD tokens contain claims like roles, groups, and permissions that, if improperly validated, can be altered to grant unauthorized access.

Consider this vulnerable Azure Function implementation:

const jwt = require('jsonwebtoken');

module.exports = async function (context, req) {
    const token = req.headers.authorization.split(' ')[1];
    const decoded = jwt.decode(token);
    
    // Vulnerable: trusts client-provided claims without validation
    if (decoded.role === 'admin') {
        context.res = {
            body: await getSensitiveData()
        };
    } else {
        context.res = { status: 403, body: 'Forbidden' };
    }
};

This code trusts the decoded JWT payload without verifying the signature or checking against Azure AD's claims validation. An attacker can modify the 'role' claim to 'admin' and bypass authorization entirely.

Another Azure-specific pattern involves Managed Identity misconfiguration. When Azure services use Managed Identity for authentication, they typically call Azure Instance Metadata Service (IMDS) at http://169.254.169.254/metadata/identity/oauth2/token. If this endpoint is accessible from the public internet or if the service doesn't properly validate the token's audience claim, attackers can obtain tokens for downstream services.

Storage account authentication bypasses also occur when Shared Access Signatures (SAS) are generated with overly permissive policies. A common mistake is using service-level SAS tokens with container-level permissions when only blob-level access is needed:

// Vulnerable SAS generation
const { generateBlobSASQueryParameters } = require('@azure/storage-blob');

const blobSAS = generateBlobSASQueryParameters({
    blobName: 'document.pdf',
    containerName: 'reports',
    permissions: 'racwd', // read, add, create, write, delete
    startsOn: new Date(),
    expiresOn: new Date(new Date().valueOf() + 86400000),
    ipRange: { start: '0.0.0.0', end: '255.255.255.255' },
    identifier: 'myPolicy',
    cacheControl: 'max-age=3600',
    contentDisposition: 'attachment',
    contentEncoding: 'utf-8',
    contentType: 'application/pdf'
}, storageAccountKey);

This grants write and delete permissions when only read access was intended. An attacker with the SAS token can modify or delete sensitive documents.

App Service authentication bypasses often occur when Easy Auth is enabled but certain endpoints are excluded from authentication. The following configuration allows unauthenticated access to API endpoints:

<configuration>
  <system.webServer>
    <handlers accessPolicy="Script,Read" />
    <security>
      <authorization>
        <denyUrlSequences>
          <clear />
        </denyUrlSequences>
      </authorization>
    </security>
    <location path="api/admin">
      <system.web>
        <authorization>
          <allow users="*" />
        </authorization>
      </system.web>
    </location>
  </system.webServer>
</configuration>

The 'api/admin' path explicitly allows all users, bypassing Azure AD authentication configured elsewhere.

Azure-Specific Detection

Detecting auth bypass in Azure requires both static analysis and dynamic testing. For static analysis, examine your Azure Function configurations, App Service auth settings, and ARM templates for misconfigurations. Look for patterns where authentication is disabled on specific paths or where token validation is incomplete.

Dynamic testing should include attempting to access endpoints with modified JWT tokens, testing for token replay attacks, and verifying that Managed Identity tokens are properly scoped. Use tools like Postman or curl to modify token claims and observe the system's response.

middleBrick's Azure-specific scanning identifies auth bypass vulnerabilities through several techniques:

First, it tests for unauthenticated access to protected endpoints by attempting requests without authentication tokens. If sensitive data is returned, this indicates a bypass.

Second, it performs token manipulation tests, modifying JWT claims like roles, permissions, and tenant IDs to see if the system properly validates them. This catches implementations that trust client-provided claims.

Third, it tests Managed Identity configurations by attempting to access the IMDS endpoint from different network contexts and verifying token audience validation.

Fourth, it examines API endpoints for proper authentication headers and tests for common bypass patterns like SQL injection in authentication queries or parameter pollution attacks.

Here's an example of how middleBrick might report an auth bypass finding:

{
  "finding": {
    "category": "Authentication Bypass",
    "severity": "High",
    "description": "Unauthenticated access to sensitive API endpoint",
    "endpoint": "/api/sensitive-data",
    "test_case": "No authentication token provided",
    "response": {
      "status": 200,
      "body_contains_sensitive_data": true
    },
    "remediation": "Implement Azure AD authentication for all API endpoints and verify token validation"
  }
}

For Azure Storage accounts, middleBrick tests SAS token permissions by attempting operations beyond the intended scope and verifies that IP restrictions and expiration times are properly enforced.

Azure-Specific Remediation

Remediating auth bypass in Azure requires implementing proper authentication and authorization patterns. For Azure Functions, always validate JWT tokens using Azure's built-in validation libraries rather than manual decoding:

const { AccessToken } = require('azure-auth-access-token');

module.exports = async function (context, req) {
    const token = req.headers.authorization.split(' ')[1];
    
    try {
        const accessToken = new AccessToken({
            token: token,
            audience: 'api://your-api-identifier',
            tenantId: 'your-tenant-id'
        });
        
        await accessToken.validate();
        
        const claims = accessToken.getClaims();
        if (claims.roles.includes('admin')) {
            context.res = {
                body: await getSensitiveData()
            };
        } else {
            context.res = { status: 403, body: 'Forbidden' };
        }
    } catch (error) {
        context.res = { status: 401, body: 'Unauthorized' };
    }
};

This approach uses Azure's native token validation, ensuring proper signature verification and claim validation.

For App Service authentication, configure Easy Auth to protect all endpoints and use Azure AD authentication providers:

<configuration>
  <system.webServer>
    <handlers accessPolicy="Script,Read" />
    <security>
      <authorization>
        <denyUrlSequences>
          <clear />
        </denyUrlSequences>
      </authorization>
    </security>
  </system.webServer>
</configuration>

Then enable Easy Auth in the Azure portal or via ARM template with Azure AD as the authentication provider, ensuring all requests go through Azure AD authentication.

For Azure Storage, implement least-privilege SAS tokens and use Azure AD RBAC for service-to-service authentication:

const { generateBlobSASQueryParameters, BlobSASPermissions } = require('@azure/storage-blob');

const blobSAS = generateBlobSASQueryParameters({
    blobName: 'document.pdf',
    containerName: 'reports',
    permissions: BlobSASPermissions.parse('r'), // read-only
    startsOn: new Date(),
    expiresOn: new Date(new Date().valueOf() + 3600000), // 1 hour
    ipRange: { start: '192.168.1.0', end: '192.168.1.255' },
    identifier: 'readOnlyPolicy'
}, storageAccountKey);

This limits permissions to read-only and restricts access to specific IP ranges.

For API Management, implement JWT validation policies to ensure tokens are properly validated before reaching backend services:

<policies>
    <validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Access token is missing or invalid.">
        <openid-config url="https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration" />
        <required-claims>
            <claim name="aud" match="all" separator=",">api://your-api-identifier</claim>
        </required-claims>
    </validate-jwt>
</policies>

This policy validates JWT tokens against Azure AD's OpenID configuration and ensures the audience claim matches your API.

Implement logging and monitoring for authentication failures using Azure Monitor and Application Insights to detect auth bypass attempts in production.

Related CWEs: authentication

CWE IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

How can I test my Azure APIs for auth bypass vulnerabilities?
Use middleBrick's self-service scanner to test your Azure API endpoints. It automatically attempts unauthenticated access, modifies JWT tokens, and tests for common bypass patterns. The scanner takes 5-15 seconds and provides specific findings with severity levels and remediation guidance. You can also manually test by attempting to access endpoints without authentication tokens, modifying token claims, and testing Managed Identity configurations.
What's the difference between authentication and authorization bypass in Azure?
Authentication bypass occurs when an attacker accesses a system without providing valid credentials at all, while authorization bypass happens when valid credentials are provided but the system grants access beyond what the user should have. In Azure, authentication bypass might involve accessing an endpoint without a token, while authorization bypass involves modifying a valid token's claims to escalate privileges. Both are serious vulnerabilities that middleBrick detects through different testing methodologies.