Skip to content

Commit 499eb49

Browse files
la14-1louisgvclaude
authored
fix(security): use StrictHostKeyChecking=accept-new in all SSH connections (#3037)
Replace StrictHostKeyChecking=no with accept-new across all E2E cloud drivers (aws, gcp, digitalocean, hetzner), the shared SSH_BASE_OPTS constant, and pull-history.ts. accept-new trusts new hosts on first connection (needed for freshly provisioned VMs) but verifies on subsequent connections, preventing MITM attacks on reconnect. Fixes #3031 Agent: style-reviewer Co-authored-by: B <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 917d34d commit 499eb49

7 files changed

Lines changed: 7 additions & 7 deletions

File tree

packages/cli/src/__tests__/ssh-cov.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ afterEach(() => {
3939

4040
describe("SSH constants", () => {
4141
it("SSH_BASE_OPTS has required non-interactive options", () => {
42-
expect(SSH_BASE_OPTS).toContain("StrictHostKeyChecking=no");
42+
expect(SSH_BASE_OPTS).toContain("StrictHostKeyChecking=accept-new");
4343
expect(SSH_BASE_OPTS).toContain("BatchMode=yes");
4444
});
4545

packages/cli/src/commands/pull-history.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ async function pullFromChild(ip: string, user: string, parentSpawnId: string, ss
117117
const sshBase = [
118118
"ssh",
119119
"-o",
120-
"StrictHostKeyChecking=no",
120+
"StrictHostKeyChecking=accept-new",
121121
"-o",
122122
"ConnectTimeout=10",
123123
"-o",

packages/cli/src/shared/ssh.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { logError, logInfo, logStep, logStepDone, logStepInline } from "./ui.js"
1111
/** Base SSH options shared across all clouds (array form for Bun.spawn). */
1212
export const SSH_BASE_OPTS: string[] = [
1313
"-o",
14-
"StrictHostKeyChecking=no",
14+
"StrictHostKeyChecking=accept-new",
1515
"-o",
1616
"UserKnownHostsFile=/dev/null",
1717
"-o",

sh/e2e/lib/clouds/aws.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ _aws_exec() {
161161
# Pass encoded command via stdin instead of shell interpolation.
162162
# This completely avoids command injection — the remote side only sees
163163
# stdin data, never an interpolated shell string.
164-
printf '%s' "${encoded_cmd}" | ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
164+
printf '%s' "${encoded_cmd}" | ssh -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/dev/null \
165165
-o ConnectTimeout=10 -o LogLevel=ERROR -o BatchMode=yes \
166166
"ubuntu@${_AWS_INSTANCE_IP}" "base64 -d | bash"
167167
}

sh/e2e/lib/clouds/digitalocean.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ _digitalocean_exec() {
186186
return 1
187187
fi
188188

189-
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
189+
ssh -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/dev/null \
190190
-o ConnectTimeout=10 -o LogLevel=ERROR -o BatchMode=yes \
191191
"root@${ip}" "printf '%s' '${encoded_cmd}' | base64 -d | bash"
192192
}

sh/e2e/lib/clouds/gcp.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ _gcp_exec() {
211211
# Pass encoded command via stdin instead of shell interpolation.
212212
# This completely avoids command injection — the remote side only sees
213213
# stdin data, never an interpolated shell string.
214-
printf '%s' "${encoded_cmd}" | ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
214+
printf '%s' "${encoded_cmd}" | ssh -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/dev/null \
215215
-o ConnectTimeout=10 -o LogLevel=ERROR -o BatchMode=yes \
216216
"${ssh_user}@${_GCP_INSTANCE_IP}" "base64 -d | bash"
217217
}

sh/e2e/lib/clouds/hetzner.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ _hetzner_exec() {
167167
# Pipe the base64 payload via stdin to the remote host. The remote bash
168168
# reads stdin, base64-decodes it, and executes the result. No user-controlled
169169
# data is interpolated into the SSH command string.
170-
printf '%s' "${encoded_cmd}" | ssh -o StrictHostKeyChecking=no \
170+
printf '%s' "${encoded_cmd}" | ssh -o StrictHostKeyChecking=accept-new \
171171
-o UserKnownHostsFile=/dev/null \
172172
-o LogLevel=ERROR \
173173
-o BatchMode=yes \

0 commit comments

Comments
 (0)