oscerd opened a new pull request, #25094:
URL: https://github.com/apache/camel/pull/25094
## The problem
`AiToolExecutor` gates the undeclared-argument filter on the parameter map
being non-empty:
```java
if (!argsCopy.isEmpty() && !spec.getParameterDefs().isEmpty()) {
Set<String> declaredParams = spec.getParameterDefs().keySet();
argsCopy.keySet().removeIf(name -> { ... }); // filter undeclared
}
```
So a tool that declares **no** parameters skips filtering entirely, and
every argument the model sends becomes an exchange header.
A tool declaring no parameters accepts none.
`AiToolParameterHelper.buildJsonSchemaFromDefs` emits `"additionalProperties":
false` **unconditionally**, so the schema such a tool advertises already
forbids every property — which is exactly the rationale the filter's own
comment cites.
This also re-introduced a bypass that was removed on purpose. Commit
`e9c4541a91ce` ("CAMEL-23621: remove backwards-compatibility bypass") stripped
the identical `isEmpty()` guard from three places:
```diff
- if (!allowedParams.isEmpty() && !allowedParams.contains(name)) {
+ if (!allowedParams.contains(name)) {
```
`LangChain4jToolsProducer` and `SpringAiToolsEndpoint` still carry the
strict form; only the newer shared executor regressed it.
## Severity
Hardening rather than a CVE. The Camel-internal prefix rejection (`camel` /
`org.apache.camel.`, case-insensitive) still applies, so the CVE-2025-27636
header-injection family is **not** reachable through this path. What is
unfiltered is arbitrary **non-Camel** header names originating from model
output — and LLM output is attacker-influenceable via prompt injection, while
tool routes commonly forward headers to downstream components (HTTP producers,
SQL named parameters).
## The fix
Drop the `&& !spec.getParameterDefs().isEmpty()` condition, so an empty
declaration means "no arguments accepted" instead of "all arguments accepted".
## Tests
- **New:** `testExecuteIgnoresUndeclaredArgumentsForToolWithoutParameters` —
arguments sent to a zero-parameter tool must not reach the exchange headers.
Verified it fails without the fix (`expected: null but was:
"should-be-ignored"`) and passes with it.
- **Adjusted:** `testCamelPrefixedArgumentsRejectedFromHeaders` used the
`noParams` tool and depended on the bypass to get its non-Camel argument
through, so the fix broke it. Simply flipping that assertion to `isNull()`
would have made the test vacuous — all four arguments would then be dropped by
the allowlist, and it would pass even if the Camel-prefix check were deleted.
Instead it now points at a new `prefixTool` that **declares** those names, so
the Camel-prefixed arguments survive the allowlist and genuinely exercise the
prefix check.
One caveat recorded in a comment: a dotted name such as
`org.apache.camel.hack` cannot be declared through the endpoint URI
(`parseParameterMetadata` splits the key on the first dot), so that one is
dropped as undeclared rather than by the prefix check.
Full `AiToolExecutorTest` suite: 13 tests, green.
## Upgrade guide
Not required — `camel-ai-tool` is new in 4.22 (CAMEL-23382) and the
permissive behaviour has never appeared in a release.
---
_Claude Code on behalf of @oscerd_
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]