fix(sandbox): scrub SSH_AUTH_SOCK from the sandbox subprocess env (#5145)

SSH_AUTH_SOCK points at the host's ssh-agent socket. A sandbox
subprocess that inherits it can sign and authenticate with every key
the agent holds (git push, ssh logins) without reading any key file --
the same credential-pointer leak class as the *_ASKPASS helpers the
env policy already scrubs deliberately. No wildcard pattern fits
(*AUTH* would strip benign names), so add an exact entry to
_BLOCKED_EXACT_NAMES.

A skill that genuinely needs the agent socket can still declare it via
required-secrets: injected values win over the blocklist by design.

Co-authored-by: zhouyujie <zhouyujie@keep.com>
This commit is contained in:
nicochow 2026-09-02 19:05:50 +08:00 committed by GitHub
parent a5ec7f2831
commit bbcfd368bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 11 additions and 0 deletions

View File

@ -84,6 +84,14 @@ _BLOCKED_EXACT_NAMES: frozenset[str] = frozenset(
"REDISCLI_AUTH",
"REDIS_AUTH",
"PGSERVICEFILE",
# ``SSH_AUTH_SOCK`` points at the host's ssh-agent socket. A sandbox
# subprocess that inherits it can sign and authenticate with every key
# the agent holds (git push, ssh logins) without ever reading a key
# file — the same credential-*pointer* leak class as the ``*_ASKPASS``
# helpers deliberately scrubbed by ``*PASS*`` above. No wildcard fits
# (``*AUTH*`` would strip benign names and ``SOCK`` is not unique to
# credentials), so it needs an exact entry.
"SSH_AUTH_SOCK",
}
)

View File

@ -191,6 +191,9 @@ class TestEnvPolicy:
"GIT_ASKPASS",
"SSH_ASKPASS",
"SUDO_ASKPASS",
# ssh-agent socket: a credential pointer like the ASKPASS helpers —
# inheriting it lets the sandbox sign with every key the agent holds.
"SSH_AUTH_SOCK",
],
)
def test_secret_like_names_are_blocked(self, name):