You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here are some key observations to aid the review process:
⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🏅 Score: 70
🧪 PR contains tests
🔒 Security concerns
Yes. The handoff payload (which may originate from untrusted sources like webhooks or Discord) directly influences MCP tool arguments in _dispatch for noc.network_snapshot.read. Although the tool name is restricted to a read-only set, the arguments are not sanitized or validated. An attacker could craft arguments that cause a read-only tool to behave unexpectedly, potentially leaking sensitive data or causing resource exhaustion. This is a prompt-injection path at the agent/tool-execution boundary.
In _dispatch, the arguments dict from the handoff payload is passed directly to mcp_runtime.call_tool without any schema validation or sanitization beyond checking it is a dict. An attacker who can inject a handoff (e.g., via a compromised webhook or Discord message) could craft arguments that cause a read-only tool like frr_vtysh_cmd to execute arbitrary commands or leak sensitive data. This is a prompt-injection path where untrusted content influences tool execution.
asyncdef_dispatch(self, capability: str, payload: dict[str, Any]) ->dict[str, Any]:
ifcapability=="noc.network_snapshot.read":
tool=str(payload.get("tool") or"")
arguments=payload.get("arguments")
iftoolnotinSNAPSHOT_TOOLSortoolinPROACTIVE_HEAVY_TOOLS:
raiseValueError(f"tool {tool!r} is not allowed for coordinator snapshots")
ifnotisinstance(arguments, dict):
raiseValueError("snapshot arguments must be an object")
result=awaitself.mcp_runtime.call_tool("hyrule", tool, arguments)
return {
"summary": f"NOC returned bounded read-only snapshot {tool}",
"tool_result": _bounded(result),
"source": "hyrule-mcp",
}
The run_worker loop has no backoff or cap on retries. If the coordinator encounters persistent errors (e.g., database connection failure, coordinator unavailability), it will keep retrying every NOC_COORDINATOR_POLL_SECONDS (default 5) indefinitely. This can lead to resource exhaustion, log flooding, and delayed recovery. A capped retry with exponential backoff should be added.
The snapshot tool arguments are not validated against expected schemas. Different MCP tools require specific fields (e.g., host, command for frr_vtysh_cmd). Passing arbitrary or malformed arguments can cause tool failures or unexpected behavior. This reduces robustness and could mask injection attempts.
asyncdef_dispatch(self, capability: str, payload: dict[str, Any]) ->dict[str, Any]:
ifcapability=="noc.network_snapshot.read":
tool=str(payload.get("tool") or"")
arguments=payload.get("arguments")
iftoolnotinSNAPSHOT_TOOLSortoolinPROACTIVE_HEAVY_TOOLS:
raiseValueError(f"tool {tool!r} is not allowed for coordinator snapshots")
ifnotisinstance(arguments, dict):
raiseValueError("snapshot arguments must be an object")
result=awaitself.mcp_runtime.call_tool("hyrule", tool, arguments)
return {
"summary": f"NOC returned bounded read-only snapshot {tool}",
"tool_result": _bounded(result),
"source": "hyrule-mcp",
}
The run_once method does not handle the case where client.claim fails (e.g., if another worker already claimed the handoff). If claim raises an exception, the handoff is not processed but the error is caught by the outer except Exception block, which incorrectly reports it as a failure. Instead, catch CoordinatorError specifically for the claim step and skip the handoff gracefully without logging a failure.
Why: The suggestion correctly identifies that a claim failure (e.g., already claimed by another worker) should not be treated as a processing failure. The improved code catches CoordinatorError specifically and skips the handoff gracefully, which improves robustness in a concurrent environment. This is a high-impact improvement.
Medium
Security
Validate snapshot arguments for safety
The _dispatch method for noc.network_snapshot.read passes arguments directly to call_tool without validating that it contains only safe, non-mutating parameters. An attacker or misconfigured caller could inject arguments that cause side effects (e.g., "command": "write memory"). Validate that the arguments do not contain any keys or values that could trigger configuration changes or destructive operations.
async def _dispatch(self, capability: str, payload: dict[str, Any]) -> dict[str, Any]:
if capability == "noc.network_snapshot.read":
tool = str(payload.get("tool") or "")
arguments = payload.get("arguments")
if tool not in SNAPSHOT_TOOLS or tool in PROACTIVE_HEAVY_TOOLS:
raise ValueError(f"tool {tool!r} is not allowed for coordinator snapshots")
if not isinstance(arguments, dict):
raise ValueError("snapshot arguments must be an object")
+ # Reject arguments that could trigger mutations+ if any(k in arguments for k in ("action", "commit", "apply", "write", "save")):+ raise ValueError("snapshot arguments contain potentially mutating keys")
result = await self.mcp_runtime.call_tool("hyrule", tool, arguments)
return {
"summary": f"NOC returned bounded read-only snapshot {tool}",
"tool_result": _bounded(result),
"source": "hyrule-mcp",
}
Suggestion importance[1-10]: 7
__
Why: The suggestion adds a security check for potentially mutating argument keys, which is a valid concern. However, the specific keys checked (e.g., "action", "commit") may not cover all possible dangerous arguments, and the suggestion does not consider that the tool itself (e.g., frr_vtysh_cmd) might already be read-only. The improvement is moderate but not critical.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Safety
Validation