How I Found SSRF In Choreo's REST API Proxy

Dipak kumar DasDipak kumar Das
4 min read

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

  1. Exposing an existing API by creating a REST API proxy.

  2. Deploying the REST API proxy.

  3. Testing the REST API proxy to verify its functionality.

  4. 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

  1. 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

Screenshot at Jun 29 18-25-48.png

Then deployed the API , which gave me the endpoint and the authentication token

image.png

Then I started testing the API by clicking the Test button. and there is option to copy the curl request to test via curl

image.png

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 .

Gif 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.

image.png

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

image.png

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

image(4)(1).png

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.

Screenshot at Aug 16 22-15-29.png

Thanks for visiting . Subscribe to my newsletter and never miss my upcoming articles.

1
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