signoz_aggregate_logs silently ignores searchText and returns the unfiltered total, while its sibling signoz_search_logs honors it #94
Labels
No labels
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/mcp-beaver#94
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found 2026-08-22 while measuring a credential exposure for
coilyco-flight-deck/infrastructure#708. This defect caused a wrong number to be published before a control query caught it.The defect
signoz_aggregate_logsaccepts asearchTextparameter, documents it as "Text to search for in log body (uses CONTAINS matching)", and silently discards it. The tool returns the count of all logs in the window and reports success.Measured over an identical 7-day window:
aggregate_logs(count, searchText='api.telegram.org/bot')aggregate_logs(count)- no filter at allaggregate_logs(count, searchText='zzzzz-nonexistent-string-qqqq')A string that cannot appear in any log returns the same total as a real one. The small deltas are just logs arriving between calls.
The same parameter works correctly on the sibling tool
search_logs(searchText='zzzzz-nonexistent-string-qqqq')So
searchTextis honored insignoz_search_logsand dropped insignoz_aggregate_logs. Two tools in the same server, same parameter name, opposite behavior. That inconsistency is what makes it dangerous - having usedsearch_logssuccessfully, there is no reason to distrustaggregate_logs.The working alternative
filterwithbody CONTAINSbehaves correctly onaggregate_logs:aggregate_logs(count, filter="body CONTAINS 'api.telegram.org/bot'")aggregate_logs(count, filter="body CONTAINS 'zzzzz-nonexistent-string-qqqq'")Note
rowsScannedis itself a tell: thesearchTextcalls scanned 6.4M rows, thefiltercalls scanned 25K. A dropped filter shows up as a scan of everything.Why this is filed at P1
It produces confidently wrong answers rather than errors. A dropped filter that returned an error, or zero, would be caught immediately. Returning a large plausible number that is silently the unfiltered total is the worst available failure mode, and it is exactly what happened today - "7,967,947 occurrences of a leaked credential" was reported before a negative control caught it. In a security context that is a wildly wrong blast-radius estimate.
Any agent or human who has counted anything in these logs with
searchTexthas a wrong number and no reason to suspect it.Two candidate layers - diagnose before fixing
The
signoz-mcppod runs two containers, and the defect could be in either:ward-mcp-forgejo.coilysiren.me/coilyco-flight-deck/mcp-beaver:258357e03385270d2e569393a9c2cf3af413d032signoz-mcp-server-docker.io/signoz/signoz-mcp-server:v0.10.0(upstream)Hypothesis, not established: the guard layer is stripping the parameter. The server's own instructions state "This server exposes only policy-approved tools", so mcp-beaver is actively mediating the tool surface. If it re-derives or filters tool schemas and drops parameters it does not recognise, that would produce exactly this symptom - and it would not be limited to SigNoz.
If the guard is the cause, the blast radius is every guarded MCP in the fleet - forgejo, discord, trello, steam, glama, skillsmp, node-stats, lunch-money, eco, bluesky. Any tool with a parameter the guard does not carry through would silently ignore it. That possibility is why this is filed here rather than against the deployment.
The alternative is that the upstream SigNoz server has the bug and mcp-beaver is innocent. Determine which before changing anything, since the two fixes live in different repos and one of them is a third party.
Acceptance
Related
This is the second silent-filter-drop found today.
coilysiren/inbox#391records that Forgejo's/issues?labels=endpoint returns the unfiltered set when a label name does not resolve in the target repo, which inflated an estate-wide P0 count before it was caught. Different system, identical failure class: a filter that cannot be applied returns everything instead of erroring.Worth treating as a standing check rather than two coincidences - any filter parameter, anywhere in the fleet, should be probed with a value that cannot match before its results are trusted.