Skip to content

chore(hardening): stop auto-approving Bash in auto mode and FetchURL by default - #5

Merged
devGregA merged 2 commits into
mainfrom
hardening/default-privileges
Aug 13, 2026
Merged

chore(hardening): stop auto-approving Bash in auto mode and FetchURL by default#5
devGregA merged 2 commits into
mainfrom
hardening/default-privileges

Conversation

@devGregA

Copy link
Copy Markdown
Contributor

Problem

Two privileges were granted implicitly rather than asked for.

  1. Auto mode blanket-approved Bash. Headless runs (kimi -p) switch the whole session into auto mode, so every shell command the model chose ran with no review — including one chosen on the strength of text that arrived in a repo file, an issue, or a fetched page. The mode is a convenience setting; it was also acting as a grant of arbitrary code execution.
  2. FetchURL was in the default auto-approve set. It is the only auto-approved tool that sends caller-chosen bytes to a caller-chosen host. Whatever the agent can read (and Read/Grep/Glob are auto-approved), it could put in a URL and ship out with no prompt. The LocalFetchURLProvider SSRF guard is solid but blocks internal targets — it does nothing about exfiltration to a public host, so the gate has to be approval.

What changed

  • auto-mode-approve skips an excluded-tool set, currently { Bash }. This does not deny Bash: the call falls through to the rest of the chain, so a user [permission] allow rule authorizes it — explicit and auditable instead of implied by the mode. KIMI_CODE_AUTO_APPROVE_BASH=1 restores the old behaviour for an operator who accepts the risk.
  • FetchURL removed from DEFAULT_APPROVE_TOOLS. [permission] allow = ["FetchURL"] restores it.

Both escape hatches route through the [permission] rules that PR #2 makes functional, so the config path is real rather than theoretical.

Behaviour change worth reviewing

This is the most user-visible PR of the set:

  • Interactive sessions will prompt the first time the agent fetches a URL.
  • Unattended kimi -p pipelines that rely on Bash will now stop unless they set the env var or add an allow rule. That is the intended outcome — the previous behaviour was the finding — but it is a breaking change for any existing automation, so it deserves a deliberate decision rather than a silent merge.

Testing

  • New: Bash is not approved by auto-mode-approve in auto mode; ordinary tools still are; the env opt-in restores approval; FetchURL is not in the default approve set.
  • Verified as real tests: with both policy files reverted, exactly the 2 new negative tests fail.
  • Two existing hook-flow tests in tool.test.ts set auto mode purely so Bash would run while they assert hook ordering. They timed out under the new behaviour (correctly — they were waiting for approval), so they now opt in via the env var. Their subject is hooks, not permissions, so this keeps them testing what they were written to test.
  • Full agent-core-v2 suite green: 310 files / 4874 tests.
  • oxlint and tsc --noEmit clean.

Checklist

  • Problem explained above (fork-local hardening; no upstream issue).
  • Tests added that prove the change works.
  • Changeset added (minor).
  • No doc update needed.

…by default

Auto mode exists to take friction out of ordinary work, and headless runs
turn it on for the whole session. Blanket-approving Bash there converts a
shell command the model chose, possibly on the strength of text it read
from a repo file or a fetched page, into unreviewed execution. Bash now
falls through the rest of the chain, so a user allow rule still authorizes
it, explicitly. KIMI_CODE_AUTO_APPROVE_BASH=1 restores the old behaviour.

Drop FetchURL from the default auto-approve set. It is the one
auto-approved tool that sends caller-chosen bytes to a caller-chosen host,
so it is the sink half of an exfiltration pair; the SSRF guard blocks
internal targets but not public ones, so the gate has to be approval.

The two Bash hook-flow tests set auto mode purely to let Bash run while
they assert hook ordering; they now opt in through the env var instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# Conflicts:
#	packages/agent-core-v2/test/agent/permissionPolicy/permissionPolicyService.test.ts
@devGregA
devGregA merged commit b8a0c47 into main Aug 13, 2026
13 checks passed
@devGregA
devGregA deleted the hardening/default-privileges branch August 13, 2026 03:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant