fix: enforce sandbox network block for agent tools
This commit is contained in:
@@ -527,6 +527,15 @@ def run_cowork(
|
|||||||
preview = {"kind": "info", "title": name, "text": str(args)}
|
preview = {"kind": "info", "title": name, "text": str(args)}
|
||||||
emit({"type": "tool_proposed", "id": tc_id, "name": name, "args": args,
|
emit({"type": "tool_proposed", "id": tc_id, "name": name, "args": args,
|
||||||
"preview": preview})
|
"preview": preview})
|
||||||
|
if ctx.block_network:
|
||||||
|
result = {"ok": False, "output": (
|
||||||
|
f"{name}: network access is blocked by the Sandbox Security Layer "
|
||||||
|
'("Block network for agent-run commands" is on in Settings).')}
|
||||||
|
emit({"type": "tool_result", "id": tc_id, "name": name,
|
||||||
|
"ok": False, "output": result["output"]})
|
||||||
|
messages.append({"role": "tool", "tool_call_id": tc_id, "name": name,
|
||||||
|
"content": result["output"]})
|
||||||
|
continue
|
||||||
# R05-T04: MCP/connector tools used to run with NO permission
|
# R05-T04: MCP/connector tools used to run with NO permission
|
||||||
# check at all — this is what closes that gap. Same policy,
|
# check at all — this is what closes that gap. Same policy,
|
||||||
# same gate object as the built-in tools below.
|
# same gate object as the built-in tools below.
|
||||||
|
|||||||
+6
-1
@@ -327,7 +327,12 @@ def run_code(
|
|||||||
else:
|
else:
|
||||||
emit({"type": "tool_start", "id": tc_id, "name": name})
|
emit({"type": "tool_start", "id": tc_id, "name": name})
|
||||||
if is_extra and extra_executor is not None:
|
if is_extra and extra_executor is not None:
|
||||||
result = extra_executor(name, args)
|
if ctx.block_network:
|
||||||
|
result = {"ok": False, "output": (
|
||||||
|
f"{name}: network access is blocked by the Sandbox Security Layer "
|
||||||
|
'("Block network for agent-run commands" is on in Settings).')}
|
||||||
|
else:
|
||||||
|
result = extra_executor(name, args)
|
||||||
else:
|
else:
|
||||||
def on_output(line: str, _id=tc_id, _name=name) -> None:
|
def on_output(line: str, _id=tc_id, _name=name) -> None:
|
||||||
emit({"type": "tool_output", "id": _id, "name": _name, "delta": line})
|
emit({"type": "tool_output", "id": _id, "name": _name, "delta": line})
|
||||||
|
|||||||
@@ -216,7 +216,8 @@ class ToolsAdminTab(QWidget):
|
|||||||
result. Respects the fetch_url toggle: when web access is OFF the agent
|
result. Respects the fetch_url toggle: when web access is OFF the agent
|
||||||
cannot reach the internet, so the test reports that instead of probing."""
|
cannot reach the internet, so the test reports that instead of probing."""
|
||||||
disabled = ("fetch_url" in self.ctx.config.tools_disabled
|
disabled = ("fetch_url" in self.ctx.config.tools_disabled
|
||||||
or not bool(self.ctx.config.agent_security.get("allow_url_fetch", True)))
|
or not bool(self.ctx.config.agent_security.get("allow_url_fetch", True))
|
||||||
|
or bool(self.ctx.config.agent_security.get("block_network", False)))
|
||||||
if disabled:
|
if disabled:
|
||||||
self.test_internet_status.setText(tr("tools_admin.internet_disabled"))
|
self.test_internet_status.setText(tr("tools_admin.internet_disabled"))
|
||||||
self.test_internet_status.setStyleSheet("color: #c00;")
|
self.test_internet_status.setStyleSheet("color: #c00;")
|
||||||
|
|||||||
@@ -233,6 +233,10 @@ class AppContext:
|
|||||||
connections across calls/turns (spawning a subprocess per turn would
|
connections across calls/turns (spawning a subprocess per turn would
|
||||||
be slow and wasteful). A server/connector that fails to connect is
|
be slow and wasteful). A server/connector that fails to connect is
|
||||||
skipped, not a hard failure for the turn."""
|
skipped, not a hard failure for the turn."""
|
||||||
|
# Sandbox Security Layer blocks agent-owned network connectors before
|
||||||
|
# they can spawn a server or issue a REST request.
|
||||||
|
if self.config.agent_security.get("block_network", False):
|
||||||
|
return [], None
|
||||||
# Master switch (Monitoring → Tools → Connector): when the admin turns
|
# Master switch (Monitoring → Tools → Connector): when the admin turns
|
||||||
# "Connect to external" off, the agent connects to NO external
|
# "Connect to external" off, the agent connects to NO external
|
||||||
# connectors/MCP at all — no subprocesses spawned, no REST calls.
|
# connectors/MCP at all — no subprocesses spawned, no REST calls.
|
||||||
|
|||||||
Reference in New Issue
Block a user