security: supply chain hardening — CI pinning, dep pinning, and code fixes (#9801)
CI/CD Hardening:
- Pin all 12 GitHub Actions to full commit SHAs (was mutable @vN tags)
- Add explicit permissions: {contents: read} to 4 workflows
- Pin CI pip installs to exact versions (pyyaml==6.0.2, httpx==0.28.1)
- Extend supply-chain-audit.yml to scan workflow, Dockerfile, dependency
manifest, and Actions version changes
Dependency Pinning:
- Pin git-based Python deps to commit SHAs (atroposlib, tinker, yc-bench)
- Pin WhatsApp Baileys from mutable branch to commit SHA
Tool Registry:
- Reject tool name shadowing from different tool families (plugins/MCP
cannot overwrite built-in tools). MCP-to-MCP overwrites still allowed.
MCP Security:
- Add tool description content scanning for prompt injection patterns
- Log detailed change diff on dynamic tool refresh at WARNING level
Skill Manager:
- Fix dangerous verdict bug: agent-created skills with dangerous
findings were silently allowed (ask->None->allow). Now blocked.
This commit is contained in:
@@ -117,11 +117,27 @@ class ToolRegistry:
|
||||
with self._lock:
|
||||
existing = self._tools.get(name)
|
||||
if existing and existing.toolset != toolset:
|
||||
logger.warning(
|
||||
"Tool name collision: '%s' (toolset '%s') is being "
|
||||
"overwritten by toolset '%s'",
|
||||
name, existing.toolset, toolset,
|
||||
# Allow MCP-to-MCP overwrites (legitimate: server refresh,
|
||||
# or two MCP servers with overlapping tool names).
|
||||
both_mcp = (
|
||||
existing.toolset.startswith("mcp-")
|
||||
and toolset.startswith("mcp-")
|
||||
)
|
||||
if both_mcp:
|
||||
logger.debug(
|
||||
"Tool '%s': MCP toolset '%s' overwriting MCP toolset '%s'",
|
||||
name, toolset, existing.toolset,
|
||||
)
|
||||
else:
|
||||
# Reject shadowing — prevent plugins/MCP from overwriting
|
||||
# built-in tools or vice versa.
|
||||
logger.error(
|
||||
"Tool registration REJECTED: '%s' (toolset '%s') would "
|
||||
"shadow existing tool from toolset '%s'. Deregister the "
|
||||
"existing tool first if this is intentional.",
|
||||
name, toolset, existing.toolset,
|
||||
)
|
||||
return
|
||||
self._tools[name] = ToolEntry(
|
||||
name=name,
|
||||
toolset=toolset,
|
||||
|
||||
Reference in New Issue
Block a user