How I Found SSRF In Choreo's REST API Proxy
So one night I was looking for some external bug bounty programs. Then I found WSO2 Security Reward and Acknowledgement Program. Within the scope of the program was a product called Choreo.
So Choreo is a digital innovation platform that allows you to develop, deploy, and manage cloud-native applications at scale. Its AI-assisted, low-code application development environment simplifies creating services, managing APIs, and building integrations while ensuring best practices and secure coding guidelines.
I started testing one functionality of Choreo called REST API Proxy
What is a REST API Proxy?
A REST API Proxy is an API proxy that complies with the Representational State Transfer(REST) standards. The REST API proxy fronts the API and is the contact point for applications that want to consume the API. Although APIs decouples the backend and the application, an API alone cannot ensure security for the backend and the application by applying policies such as security, rate-limiting, etc. This is where a REST API Proxy comes into play. A REST API Proxy helps you manage the API by applying necessary security policies, access-control policies, and even collecting analytics. Fronting your unmanaged API by a REST API proxy gives your application the flexibility to make changes to the back-end API without affecting the applications that consume them.
A REST API Proxy exposes an endpoint that applications use to consume the API.
So the Choreo API Proxy functionality Works like below
Exposing an existing API by creating a REST API proxy.
Deploying the REST API proxy.
Testing the REST API proxy to verify its functionality.
Manage your REST API proxy by adding rate limiting and security policies and leveraging the platform's API management capabilities.
So lets start how I manage to find a SSRF in that functionality
First I created a dummy api proxy with target https://google.com , then i deployed the API and got invoke URL as below
https://c7000d34-e8b2-4669-89c7-5fb9b8b46d00-dev.e1-us-east-azure.choreoapis.dev/vjvn/defaultapi/1.0.0
From the URL structure dev.e1-us-east-azure.choreoapis.dev
I got confirmation that the application API is hosted on Azure
So thought to give a try for SSRF
- Collected the metadata URL for azure from the Cloud Metadata directory
http://169.254.169.254/metadata/instance?api-version=2017-04-02
http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-04-02&format=text
Then Created a new REST API Proxy with endpoint set to http://169.254.169.254/metadata/instance?api-version=2017-04-02
Then deployed the API , which gave me the endpoint and the authentication token
Then I started testing the API by clicking the Test button. and there is option to copy the curl request to test via curl
Then I got response Bad request: . Required metadata header not specified
This error confirmed that there is interaction with the azure , after googling the error found out that there is extra HTTP header Metadata=true
required to access metadata.
So I added the header in the curl with -H flag
curl "https://c7000d34-e8b2-4669-89c7-5fb9b8b46d00-dev.e1-us-east-azure.choreoapis.dev/vjvn/defaultapia/1.0.0/" -H 'Metadata=true' -H 'API-Key: eyJXXXX' -X GET
Then after setting the header the header error gone but I got another error
{"error":"Bad request. api-version is invalid or was not specified in the request. For more information refer to aka.ms/azureimds","newest-versions":["2021-12-13","2021-11-15","2021-11-01"]}
After lot of debugging found out that I set the endpoint as http://169.254.169.254/metadata/instance?api-version=2017-04-02
so the whole URL is not getting passed with the request or the version I am using no longer supported . So I tried with the version 2021-12-13
still I got the same api-version error like before.
After scratching my head , I got one idea .
To create a new REST API Proxy with Endpoint http://169.254.169.254
and append the path /metadata/instance?api-version=2017-04-02
in Invoke URL endpoint in the curl command.
Then deployed the API , opened the testing console via curl and set the path to /metadata/instance
and added one parameter api-version
with value 2017-04-02
Then copied the Curl command and added the extra HTTP header Metadata=true
curl "https://f61db5e1-4378-4746-bdc8-4b00a65701b5-dev.e1-us-east-azure.choreoapis.dev/ujfn/defaultapiadghdg/1.0.0/metadata/instance?api-version=2017-04-02" -H 'Metadata: true' -H 'API-Key: eyJrXXXXX' -X GET
And guess what it's worked like a charm and got the metadata
After this stopped further testing and quickly created the POC and reported to the vendor.
WSO2 Team fixed the issue within a day . I got a bounty, certificate and got acknowledged in their acknowledgement page.
Thanks for visiting . Subscribe to my newsletter and never miss my upcoming articles.
Subscribe to my newsletter
Read articles from Dipak kumar Das directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Dipak kumar Das
Dipak kumar Das
Security Engineer