bountyyfi/Azure-APIM-Cross-Tenant-Signup-Bypass
GitHub: bountyyfi/Azure-APIM-Cross-Tenant-Signup-Bypass
披露 Azure APIM Developer Portal 跨租户注册绕过漏洞,提供检测脚本与 Nuclei 模板用于安全审计。
Stars: 33 | Forks: 0
# Azure APIM 跨租户注册绕过
## 安全公告
**[GHSA-vcwf-73jp-r7mv](https://github.com/bountyyfi/Azure-APIM-Cross-Tenant-Signup-Bypass/security/advisories/GHSA-vcwf-73jp-r7mv)**
## 概述
Azure API Management (APIM) Developer Portal 中存在一个安全漏洞,允许攻击者在任何启用了 Basic Authentication 的 APIM 实例上注册账户,即使管理员已在门户 UI 中禁用了用户注册。
此绕过使得跨租户账户创建成为可能,可能导致对 API 文档、订阅密钥以及通过 Developer Portal 暴露的其他资源的未授权访问。
## 披露时间线
|日期 |动作 |
|----------|-------------------------------------------------------|
|2025-09-30|发现漏洞 |
|2025-09-30|向 MSRC 提交初始报告 |
|2025-10-30|MSRC 回复:以“非漏洞”为由关闭 |
|2025-11-01|向 MSRC 提交包含更多细节的第二份报告|
|2025-11-20|MSRC 回复:以“设计如此”为由关闭 |
|2025-11-20|报告给 CERT-FI |
|2025-11-26|公开披露 |
|2025-11-27|向 MITRE 申请 CVE |
## 漏洞详情
### 问题所在
当 Azure APIM 为 Developer Portal 配置了 Basic Authentication 时,管理员可以通过 Azure Portal UI 禁用用户注册。然而,这仅仅隐藏了门户界面中的注册表单。
底层的注册 API endpoint 仍然处于活动状态并直接接受注册请求,完全绕过了 UI 限制。
### 根本原因
两个问题结合导致了此漏洞:
1. **仅 UI 层面的限制**:禁用注册只是隐藏了门户 UI 中的表单。后端的注册 API 仍然活跃且可访问。
2. **无租户验证**:注册 API 不验证请求是否源自同一租户的门户。请求可以从任何来源精心构造,以在任何易受攻击的实例上进行注册。
### 攻击向量
该攻击需要两个 APIM 实例:
1. **攻击者的实例**:任何启用了注册的 APIM Developer Portal(或攻击者自己的 APIM 实例)
2. **目标实例**:受害者的 APIM Developer Portal,在 UI 中“禁用”了注册,但仍配置了 Basic Authentication
**步骤:**
1. 攻击者访问自己的 APIM Developer Portal 注册页面(注册已启用)
2. 攻击者填写注册表单并拦截请求(例如,使用 Burp Suite)
3. 攻击者将 `Host` header 从其实例更改为目标实例
4. 攻击者提交修改后的请求
5. 尽管管理控制台中注册已“禁用”,账户仍在目标实例上创建
6. 攻击者以注册用户身份获得对目标 Developer Portal 的访问权限
**关键技术细节:** 跨租户绕过通过操纵注册 POST 请求中的 `Host` header 实现。`/signup` endpoint 根据 Host header 处理请求,而不验证租户边界。
请求操纵示例:
```
POST /signup HTTP/1.1
Host: target-apim.developer.azure-api.net <-- Changed from attacker's instance
Origin: https://attacker-apim.developer.azure-api.net
Content-Type: application/json
{"challenge":{...},"signupData":{"email":"attacker@email.com",...}}
```
核心问题:在 UI 中禁用注册并不会禁用底层 API。API endpoint 接受基于 Host header 的跨租户请求。
## 影响
- **跨租户账户创建** - 在任何启用了 Basic Auth 的 APIM 实例上注册
- **绕过管理控制** - 注册限制无效
- **访问 API 文档** - 可能包含敏感的内部信息
- **请求 API 订阅密钥的潜在可能** - 取决于门户配置
- **内部门户暴露** - 外部攻击者可以在“内部”门户上注册
## 受影响的配置
您的 APIM 实例在以下情况下易受攻击:
- 配置了 Basic Authentication 身份提供商(即使在 UI 中“禁用”了注册)
- Developer Portal 已部署且可访问
您的 APIM 实例在以下情况下**不**易受攻击:
- Basic Authentication 身份提供商已完全移除(不仅仅是注册被禁用)
- 仅配置了 Azure AD / OAuth 身份验证
- Developer Portal 未部署或已禁用
**关键点:** 在 Azure Portal UI 中禁用注册是**不**够的。必须完全移除 Basic Authentication 身份提供商以防止跨租户注册绕过。
## Azure 资源属性
使用这些属性值通过 Azure Resource Graph、ARM 模板或 Azure Policy 识别易受攻击的 APIM 实例。
### 易受攻击的配置属性
| 属性路径 | 易受攻击的值 | 描述 |
|---------------|------------------|-------------|
| `properties.developerPortalStatus` | `Enabled` | Developer Portal 可访问 |
| `sku.name` | `Developer`, `Basic`, `Standard`, `Premium` | 非消费层(消费层门户功能有限) |
### 身份提供商检查(子资源)
Basic Authentication 身份提供商是 APIM 实例下的一个独立资源:
```
Resource Type: Microsoft.ApiManagement/service/identityProviders
Name: basic
```
**如果存在则易受攻击:** 存在 `basic` 身份提供商资源表明已配置 Basic Authentication。
### 门户注册设置(子资源)
```
Resource Type: Microsoft.ApiManagement/service/portalsettings/signup
Property: properties.enabled
```
| 属性 | 值 | 含义 |
|----------|-------|---------|
| `properties.enabled` | `true` | 注册在 UI 中可见 |
| `properties.enabled` | `false` | 注册在 UI 中隐藏(如果存在 Basic Auth,API 仍然有效!) |
### Azure Resource Graph 查询
使用此查询查找可能易受攻击的 APIM 实例:
```
resources
| where type == "microsoft.apimanagement/service"
| where properties.developerPortalStatus == "Enabled"
| where sku.name != "Consumption"
| project name, resourceGroup, subscriptionId, location, sku.name, properties.developerPortalStatus
```
检查 Basic Auth 身份提供商:
```
resources
| where type == "microsoft.apimanagement/service/identityproviders"
| where name endswith "/basic"
| project apimInstance=tostring(split(id, "/providers/Microsoft.ApiManagement/service/")[1]), resourceGroup, subscriptionId
```
### Azure CLI 命令
检查 Developer Portal 状态:
```
az apim show --name --resource-group --query "{name:name, portalStatus:developerPortalStatus, sku:sku.name}"
```
列出身份提供商(检查 'basic'):
```
az apim identity-provider list --resource-group --service-name --query "[].name"
```
检查注册设置:
```
az rest --method get --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.ApiManagement/service//portalsettings/signup?api-version=2022-08-01" --query "properties.enabled"
```
### 汇总表
| 条件 | 属性/资源 | 易受攻击的值 |
|-----------|-------------------|------------------|
| 门户已启用 | `properties.developerPortalStatus` | `== 'Enabled'` |
| 非消费层 SKU | `sku.name` | `!= 'Consumption'` |
| Basic Auth 存在 | `identityProviders/basic` 资源 | 资源存在 |
| 注册已隐藏(可能绕过) | `portalsettings/signup.properties.enabled` | `== false`(带有 Basic Auth) |
**关键组合:** 当满足以下条件时,实例容易受到注册绕过:
- `properties.developerPortalStatus == 'Enabled'` 且
- `identityProviders/basic` 资源存在 且
- `portalsettings/signup.properties.enabled == false`
## 识别您组织的 APIM 实例
### Google Dorks
**查找带有 Basic Auth 注册的门户(最有可能易受攻击):**
```
site:developer.azure-api.net "Sign up" "Email" "Password"
```
```
site:developer.azure-api.net "Create account" "Username"
```
```
site:developer.azure-api.net inurl:/signup "register"
```
**查找带有登录页面的门户(表明可能配置了 Basic Auth):**
```
site:developer.azure-api.net "Sign in" "Email" "Password" -"Azure AD" -"Microsoft account"
```
```
site:developer.azure-api.net inurl:/signin "password"
```
**查找暴露了 API 文档的 Developer Portal:**
```
site:developer.azure-api.net inurl:/apis "Subscribe"
```
```
site:developer.azure-api.net "API" "Products" "Subscribe"
```
**常规发现:**
```
site:*.developer.azure-api.net
```
```
inurl:developer.azure-api.net "Developer Portal"
```
### Shodan
**查找 APIM Developer Portal:**
```
http.title:"Developer Portal" http.html:"azure-api.net"
```
```
ssl.cert.subject.cn:"*.developer.azure-api.net"
```
```
http.html:"developerPortal" http.html:"azure"
```
### Nuclei 批量扫描
发现目标后,使用 Nuclei 进行扫描:
```
# 保存目标到文件
echo "https://target1.developer.azure-api.net" > targets.txt
echo "https://target2.developer.azure-api.net" >> targets.txt
# 批量扫描
nuclei -t azure-apim-signup-bypass.yaml -l targets.txt -o vulnerable.txt
```
### 组织的资产发现
如果您的组织使用 Azure APIM,您可以使用以下方法识别自己的实例:
**Azure Portal:**
- 导航到 Azure Portal → All Resources → 按 "API Management" 筛选
- 或使用 Azure Resource Graph Explorer 配合上一节的查询
**Azure CLI(针对您的订阅):**
```
# 列出订阅中的所有 APIM 实例
az apim list --query "[].{name:name, resourceGroup:resourceGroup, url:developerPortalUrl}"
```
### 验证您自己的实例
使用这些方法检查**您**组织的 APIM 实例是否易受攻击:
**使用验证脚本:**
```
# 检查您自己的实例
python apim_vuln_checker.py https://YOUR-ORG.developer.azure-api.net
# 包含 Azure RM 属性检查 (推荐用于内部审计)
python apim_vuln_checker.py --azure -s YOUR-SUB-ID -g YOUR-RG -n YOUR-APIM-NAME
```
**使用 Nuclei 进行内部安全审计:**
```
# 扫描您组织的 APIM 实例
nuclei -t azure-apim-signup-bypass.yaml -u https://YOUR-ORG.developer.azure-api.net
```
### 易受攻击配置的指标
在审计您自己的实例时,请查找:
- Developer Portal 显示带有电子邮件/密码字段的“注册”(而不仅仅是“使用 Microsoft 登录”)
- Azure Portal 中配置了 Basic Authentication 身份提供商
- 注册在 UI 中“禁用”,但 Basic Auth 提供商仍然存在
**非易受攻击指标:**
- 仅显示“使用 Microsoft 登录”或“Azure AD”选项
- 未配置 Basic Authentication 身份提供商
- Developer Portal 完全禁用
### 授权渗透测试
如果您是进行授权测试的安全专业人员:
1. 确保您拥有系统所有者的**书面授权**
2. 记录您的参与范围和边界
3. 遵循负责任的披露做法
4. 向组织报告发现,不要公开利用它们
### 负责任的披露
如果您发现易受攻击的第三方 APIM 实例:
1. **不要**尝试创建账户或访问系统
2. 直接联系组织的安全团队
3. 向他们提供此公告以便其进行修复
4. 在任何披露之前留出合理的修复时间
## 验证脚本
提供了一个 Python 脚本以检查您的 APIM 实例是否易受攻击。
### 安装
```
# 基本安装 (仅 HTTP probe)
pip install requests colorama
# 完整安装 (包含 Azure RM 属性检查)
pip install requests colorama azure-identity
```
### 用法
该脚本支持两种模式:
1. **HTTP Probe** - 通过 Developer Portal endpoint 进行外部黑盒检查
2. **Azure RM Check** - 通过 Azure Resource Manager API 进行内部属性检查
```
# HTTP probe (外部检查)
python apim_vuln_checker.py https://your-apim.developer.azure-api.net
# Azure RM 属性检查 (需要 az login)
python apim_vuln_checker.py --azure -s -g -n
# 组合检查 (HTTP probe 和 Azure RM)
python apim_vuln_checker.py https://your-apim.developer.azure-api.net \
--azure -s -g -n
# 详细输出
python apim_vuln_checker.py https://your-apim.developer.azure-api.net -v
# 跳过 SSL 验证
python apim_vuln_checker.py https://your-apim.developer.azure-api.net -k
# JSON 输出
python apim_vuln_checker.py https://your-apim.developer.azure-api.net --json
```
### Azure RM 属性检查
使用 `--azure` 模式时,脚本直接查询 Azure Resource Manager API 以检查:
| 属性 | 易受攻击的值 |
|----------|------------------|
| `properties.developerPortalStatus` | `== 'Enabled'` |
| `sku.name` | `!= 'Consumption'` |
| `identityProviders/basic` 资源 | 存在 |
| `portalsettings/signup.properties.enabled` | `== false` |
**Azure RM 模式的先决条件:**
1. 安装 `azure-identity`:`pip install azure-identity`
2. 通过 Azure 认证:`az login`
3. 确保您对 APIM 资源拥有 Reader 访问权限
### 示例输出
```
___ __ ____
/ _ )___ __ _____ / /___ ____ __ / __ \__ __
/ _ / _ \/ // / _ \/ __/ // / // / / /_/ / // /
/____/\___/\_,_/_//_/\__/\_, /\_, / \____/\_, /
/___//___/ /___/
Author: Mihalis Haatainen, Bountyy Oy - www.bountyy.fi
======================================================================
Azure APIM Vulnerability Checker
Cross-Tenant Signup Bypass Detection
======================================================================
[?] Checking signup endpoint accessibility...
[i] Signup endpoint is accessible
[?] Checking if Basic Auth signup API is accessible...
[!] Basic Auth signup API ACTIVE (captcha validation)
[?] Checking if signup is hidden/disabled in UI...
[i] Signup page returns 404 (hidden in UI)
======================================================================
VULNERABILITY ASSESSMENT RESULTS
======================================================================
Target: https://example.developer.azure-api.net
Risk Level: CRITICAL - VULNERABLE TO SIGNUP BYPASS
Detailed Checks:
[!] signup_ui: Signup endpoint is accessible
[!] basic_auth_api: Basic Auth signup API ACTIVE (captcha validation)
[+] signup_ui_hidden: Signup page returns 404 (hidden in UI)
Recommendations:
CRITICAL: SIGNUP BYPASS VULNERABILITY CONFIRMED
The Basic Auth signup API is accessible even though UI hides signup.
Attackers can register accounts by calling the API directly.
Immediate actions:
1. DISABLE Basic Authentication in Azure Portal immediately
2. Audit all developer portal user accounts for unauthorized signups
3. Review user creation logs - check for API-based registrations
4. Implement Azure AD authentication only
```
## Nuclei 模板
提供了一个 Nuclei 模板用于自动化扫描。
### 用法
```
# 单个目标
nuclei -t azure-apim-signup-bypass.yaml -u https://target.developer.azure-api.net
# 从文件读取多个目标
nuclei -t azure-apim-signup-bypass.yaml -l targets.txt
# 使用代理 (用于调试)
nuclei -t azure-apim-signup-bypass.yaml -u https://target.developer.azure-api.net -proxy http://127.0.0.1:8080
# 跳过 SSL 验证
nuclei -t azure-apim-signup-bypass.yaml -u https://target.developer.azure-api.net -insecure
```
### 模板详情
- 向 `/signup` endpoint 发送带有测试 captcha 数据的 POST 请求
- 通过检查 captcha/验证错误响应来检测活动的注册 API
- CVSS 评分:6.5(中高)
- CWE-284:不当访问控制
## 缓解措施
### 立即行动
1. **完全移除 Basic Authentication 身份提供商** 在 Azure Portal 中:
- 导航到您的 APIM 实例
- 转到 Developer Portal -> Identities
- 完全删除“Username and password”身份提供商
- 注意:仅仅在 UI 中禁用注册是**不**够的
1. **审计现有账户**:
- 审查所有 Developer Portal 用户账户
- 查找通过 API 创建的账户(检查创建时间戳和模式)
- 移除任何未授权账户
1. **启用 Azure AD 身份验证**:
- 将 Azure AD 配置为唯一身份提供商
- 这强制执行适当的租户边界
### 长期建议
- 仅使用 Azure AD 身份验证
- 不要依赖 UI 级别的注册限制
- 监控 Developer Portal 注册活动
- 定期审计门户用户账户
## Microsoft 的回应
Microsoft Security Response Center (MSRC) 收到了两次关于此漏洞的通知。两份报告均以以下裁定关闭:
尽管绕过了管理控制并具有跨租户影响,MSRC 不认为这是一个安全漏洞。
## 文件
- `apim_vuln_checker.py` - Python 漏洞验证脚本
- `azure-apim-signup-bypass.yaml` - 用于自动化扫描的 Nuclei 模板
- `README.md` - 本文件
## 作者
**Mihalis Haatainen**
Bountyy Oy - 芬兰渗透测试和安全研究公司
- 网站:[www.bountyy.fi](https://www.bountyy.fi)
## 许可证
本公告及相关工具出于防御目的发布。请负责任地使用。
MIT 许可证 - 详情请参阅 LICENSE 文件。
## 参考资料
- [博客文章:当“Disabled”并不意味着禁用时](https://www.itewiki.fi/p/when-disabled-doesn-t-mean-disabled-azure-apim-cross-tenant-signup-bypass)
- [Azure API Management 文档](https://docs.microsoft.com/en-us/azure/api-management/)
- [APIM Developer Portal 概述](https://docs.microsoft.com/en-us/azure/api-management/api-management-howto-developer-portal)
标签:API安全, Azure APIM, Basic Authentication, CISA项目, CVE, JSON输出, MSRC, 安全披露, 开发者门户, 微软Azure, 数字签名, 无服务器架构, 服务器监控, 未授权访问, 注册绕过, 跨租户攻击, 身份验证绕过, 逆向工具, 逻辑漏洞, 配置缺陷