Webhook-url-http-3a-2f-2f169.254.169.254-2fmetadata-2fidentity-2foauth2-2ftoken
GET /metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com HTTP/1.1 Host: 169.254.169.254 Metadata: true
The metadata service dutifully hands over a JSON Web Token (JWT) . This is a high-level digital badge that says, "I am the Admin Server."
Even if the server does not directly output the response, SSRF can be combined with (like the Metadata: true header in Azure). An advanced attacker may exploit a partial SSRF that allows setting headers or using different HTTP methods.
If an attacker can trick your server into making a request to http://169.254.169.254/metadata/identity/oauth2/token (with proper headers, e.g., Metadata: true ), the service returns a JSON object containing: GET /metadata/identity/oauth2/token
GET /metadata/identity/oauth2/token?api-version=2018-02-01&resource= https://management.azure.com/ HTTP/1.1 Host: 169.254.169.254 Metadata: true
:
If you are working with Azure security, I can help you check if your VMs are properly configured against these attacks. If an attacker can trick your server into
def is_safe_webhook_url(user_input): decoded = unquote(user_input) parsed = urlparse(decoded) if parsed.scheme not in ('http', 'https'): return False # Resolve hostname to IP import socket try: ip = socket.gethostbyname(parsed.hostname) except: return False # Reject private, link-local, loopback private = ipaddress.ip_network('10.0.0.0/8') link_local = ipaddress.ip_network('169.254.0.0/16') loopback = ipaddress.ip_network('127.0.0.0/8') ip_obj = ipaddress.ip_address(ip) if ip_obj in private or ip_obj in link_local or ip_obj in loopback: return False # Additional: allowlist check allowed = ['api.yourservice.com'] if parsed.hostname not in allowed: return False return True
Attackers often encode payloads to evade naive filtering (e.g., blocking the string 169.254.169.254 ). The hyphen-and-hex format seen here is uncommon but effective for bypassing simple regex checks. It also helps the payload survive in logs or JSON without breaking syntax.
The most effective defense against SSRF targeting metadata services is preventing the application container or server from talking to local addresses. It also helps the payload survive in logs
The IP address 169.254.169.254 is a used by all major cloud service providers (AWS, Azure, GCP) to provide instance metadata to running virtual machines. This endpoint is only accessible from within the virtual machine itself, providing information about the instance's identity, network configuration, and assigned roles without requiring external authentication. The Specific Webhook: /metadata/identity/oauth2/token
When configuring a or an API connector within a container or VM, you might need to supply a token for authentication. The IMDS endpoint can be called to retrieve this token on demand. Technical Requirements for the Request GET Request: The request must be a GET request.
