From 83eeaca768f50d69a5de9ed100074418929976a5 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Fri, 30 Oct 2026 08:39:48 +0000 Subject: [PATCH] upstream: when StrictHostkeyChecking=no and an changed/revoked host key was permitted by the user anyway, ssh(1) turns off a bunch of more risk options including various forwardings. Unfortunately we had previously neglected to turn them off over the mux channel. Anthropic ANT-2026-VFW3JCKW OpenBSD-Commit-ID: ad9c14298107c0d8891f68baddef63bfc976cac9 --- clientloop.c | 10 +++++++++- mux.c | 14 +++++++++++++- sshconnect.c | 11 ++++++++++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/clientloop.c b/clientloop.c index 0df129113..6e6526aee 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.427 2026/09/16 23:26:41 jsg Exp $ */ +/* $OpenBSD: clientloop.c,v 1.428 2026/10/30 08:39:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -128,6 +128,9 @@ extern char *host; */ extern char *forward_agent_sock_path; +/* Set if we continued past a host key verification failure (sshconnect.c) */ +extern int hostkey_untrusted; + /* * Flag to indicate that we have received a window change signal which has * not yet been processed. This will cause a message indicating the new @@ -1068,6 +1071,11 @@ process_cmdline(struct ssh *ssh) } logit("Canceled forwarding."); } else { + if (hostkey_untrusted) { + logit("Port forwarding is disabled to avoid " + "monster-in-the-middle attacks."); + goto out; + } /* -R specs can be both dynamic or not, so check both. */ if (remote) { if (!parse_forward(&fwd, s, 0, remote) && diff --git a/mux.c b/mux.c index 5b34dba2b..d06fadefe 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.118 2026/10/30 08:27:49 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.119 2026/10/30 08:39:48 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -58,6 +58,9 @@ extern char *host; extern struct sshbuf *command; extern volatile sig_atomic_t quit_pending; +/* from sshconnect.c */ +extern int hostkey_untrusted; + /* Context for session open confirmation callback */ struct mux_session_confirm_ctx { u_int want_tty; @@ -837,6 +840,15 @@ mux_master_process_open_fwd(struct ssh *ssh, u_int rid, break; } + /* Forwarding was disabled when the host key failed verification */ + if (hostkey_untrusted) { + logit_f("refusing %s: host key is not trusted", fwd_desc); + reply_error(reply, MUX_S_PERMISSION_DENIED, rid, + "Port forwarding is disabled to avoid " + "man-in-the-middle attacks"); + goto out; + } + if (options.control_master == SSHCTL_MASTER_ASK || options.control_master == SSHCTL_MASTER_AUTO_ASK) { if (!ask_permission("Open %s on %s?", fwd_desc, host)) { diff --git a/sshconnect.c b/sshconnect.c index 202820be3..f3aa89da5 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.392 2026/10/30 08:21:42 djm Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.393 2026/10/30 08:39:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -58,6 +58,14 @@ struct sshkey *previous_host_key = NULL; +/* + * Set if the host key failed verification and we continued anyway + * (StrictHostKeyChecking=no). Used to refuse MITM-able forwarding + * requests that arrive after the connection is established, e.g. + * from multiplexing clients. + */ +int hostkey_untrusted = 0; + static int matching_host_key_dns = 0; static volatile pid_t proxy_command_pid = 0; @@ -1417,6 +1425,7 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo, * the connection but without MITM-able authentication or * forwarding. */ + hostkey_untrusted = 1; if (options.password_authentication) { error("Password authentication is disabled to avoid " "man-in-the-middle attacks.");