mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-17 01:26:40 +03:00
fix(cli): stop leaking API keys to CLI app subprocesses
Installed CLI apps were started with os.environ.copy(), so provider keys from the parent process were visible to untrusted binaries. Use a minimal allowlist env matching the shell tool. Fixes #4783
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
"""CLI app subprocesses must not inherit API keys from the parent environ."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from nanobot.apps.cli.service import CliAppManager
|
||||
|
||||
|
||||
def test_subprocess_env_excludes_api_keys(monkeypatch, tmp_path) -> None:
|
||||
monkeypatch.setenv("OPENAI_API_KEY", "sk-should-not-leak")
|
||||
monkeypatch.setenv("ANTHROPIC_API_KEY", "sk-ant-leak")
|
||||
monkeypatch.setenv("OPENROUTER_API_KEY", "sk-or-leak")
|
||||
|
||||
manager = CliAppManager(workspace=tmp_path, data_dir=tmp_path / "cli-apps")
|
||||
env = manager._subprocess_env()
|
||||
|
||||
assert "OPENAI_API_KEY" not in env
|
||||
assert "ANTHROPIC_API_KEY" not in env
|
||||
assert "OPENROUTER_API_KEY" not in env
|
||||
assert env.get("PYTHONUNBUFFERED") == "1"
|
||||
assert "PATH" in env
|
||||
|
||||
|
||||
def test_run_passes_filtered_env(monkeypatch, tmp_path) -> None:
|
||||
monkeypatch.setenv("OPENAI_API_KEY", "sk-should-not-leak")
|
||||
manager = CliAppManager(workspace=tmp_path, data_dir=tmp_path / "cli-apps")
|
||||
captured: dict[str, object] = {}
|
||||
|
||||
def fake_run(*args, **kwargs):
|
||||
captured.update(kwargs)
|
||||
|
||||
class Result:
|
||||
returncode = 0
|
||||
stdout = "ok"
|
||||
stderr = ""
|
||||
|
||||
return Result()
|
||||
|
||||
monkeypatch.setattr("nanobot.apps.cli.service.subprocess.run", fake_run)
|
||||
monkeypatch.setattr(manager, "get_app", lambda name: {"name": name, "entry_point": "echo"})
|
||||
monkeypatch.setattr(
|
||||
manager,
|
||||
"_load_installed",
|
||||
lambda: {"echo": {"entry_point": "echo"}},
|
||||
)
|
||||
monkeypatch.setattr("nanobot.apps.cli.service.shutil.which", lambda entry: "/bin/echo")
|
||||
monkeypatch.setattr(manager, "_resolve_cwd", lambda *a, **k: tmp_path)
|
||||
monkeypatch.setattr(manager, "_artifact_snapshot", lambda cwd: {})
|
||||
monkeypatch.setattr(manager, "_changed_artifacts", lambda cwd, snap: [])
|
||||
|
||||
manager.run("echo", ["hi"])
|
||||
|
||||
env = captured.get("env")
|
||||
assert isinstance(env, dict)
|
||||
assert "OPENAI_API_KEY" not in env
|
||||
Reference in New Issue
Block a user