May 15, 2026·6 min read·5 visits
goshs versions before 2.0.7 disable SSH host key verification when establishing remote tunnels. This flaw allows an attacker with a privileged network position to intercept the SSH connection and access the underlying unencrypted HTTP traffic.
A critical vulnerability in the Go-based file server goshs allows transparent Man-in-the-Middle (MITM) attacks during SSH tunnel establishment. By utilizing ssh.InsecureIgnoreHostKey() as the HostKeyCallback, versions prior to 2.0.7 fail to validate remote server identity.
The goshs application is a single-binary file server written in Go. It includes a feature to expose local files to the internet via an SSH reverse tunnel using the --tunnel flag. The default tunneling provider is typically a service like localhost.run.
When this tunneling feature is invoked, the application acts as an SSH client. It establishes an outbound TCP connection over port 22 and negotiates an SSH session to set up remote port forwarding. This session encapsulates the HTTP traffic between external clients and the local file server.
In versions prior to 2.0.7, the SSH client configuration intentionally disables host key verification. This configuration flaw (CWE-295) breaks the cryptographic trust model of the SSH protocol. It exposes the tunnel connection to Man-in-the-Middle (MITM) attacks by allowing any remote endpoint to impersonate the legitimate tunnel server.
An attacker exploiting this vulnerability gains the ability to intercept, read, and modify all HTTP traffic routed through the tunnel. Because TLS is typically terminated at the tunnel provider rather than the local goshs instance, the intercepted traffic is strictly unencrypted HTTP data.
The vulnerability stems from the improper implementation of the golang.org/x/crypto/ssh package. The Go SSH library enforces strict security by default and requires developers to explicitly define a HostKeyCallback function in the ssh.ClientConfig struct. This callback is responsible for validating the public key presented by the SSH server during the cryptographic handshake.
In the vulnerable implementation, the developers assigned ssh.InsecureIgnoreHostKey() to this callback field. This helper function is designed exclusively for testing and debugging environments. It returns a callback that unconditionally accepts any host key, bypassing the identity verification phase entirely.
The absence of this verification removes the primary defense against connection interception. When an SSH client ignores the host key, it cannot differentiate between the authentic server and an attacker-controlled proxy. The cryptographic handshake completes successfully, but the session keys are negotiated with the attacker rather than the intended endpoint.
This flaw highlights a common developmental anti-pattern. Developers frequently implement InsecureIgnoreHostKey() to bypass initial setup friction during development but fail to implement a proper Trust-On-First-Use (TOFU) or certificate authority system before production release.
The specific vulnerability exists in the SSH client initialization block within the tunneling logic. The vulnerable code constructs the ssh.ClientConfig struct and explicitly instructs the library to ignore host key verification.
// Vulnerable Implementation (Prior to v2.0.7)
config := &ssh.ClientConfig{
User: "tunnel",
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}The fix introduced in commit 8f409cb08aacc6e94704334e8b1fb2cd50f5dd98 completely overhauls this logic. It removes the insecure callback and implements a standard Trust-On-First-Use (TOFU) mechanism using the golang.org/x/crypto/ssh/knownhosts package.
// Patched Implementation (v2.0.7)
hostKeyCb, err := buildTOFUCallback(knownHostsPath)
if err != nil {
// handle error
}
config := &ssh.ClientConfig{
User: "tunnel",
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
HostKeyCallback: hostKeyCb,
}The new buildTOFUCallback function relies on a local configuration file (~/.config/goshs/known_hosts). When a connection is established, the callback checks this file. If the host is unknown, the key is written to the file. If the host is known but the presented key differs, the library raises a HostKeyMismatchError, terminating the connection immediately.
To exploit this vulnerability, an attacker must secure a privileged network position between the goshs instance and the target tunnel provider. This position is typically achieved via local network attacks (ARP spoofing, DNS hijacking) or broader infrastructure compromise (BGP hijacking, malicious ISP routing).
Once positioned, the attacker configures a malicious SSH daemon to listen for intercepted traffic. When the victim initializes goshs with the --tunnel flag, the outbound TCP connection to port 22 is redirected to the attacker's daemon. The attacker's daemon presents a newly generated, arbitrary RSA or Ed25519 host key to the client.
Because goshs employs the InsecureIgnoreHostKey() callback, the client silently accepts this fraudulent key. The attacker's proxy then establishes a secondary, legitimate SSH session with the actual tunnel provider. This dual-session architecture allows the attacker to act as a transparent proxy.
The resulting compromise yields full access to the encapsulated HTTP traffic. Since TLS termination occurs at the tunnel provider's edge, the inner payload traversing the SSH tunnel is unencrypted. The attacker acquires read and write access to directory listings, downloaded files, and uploaded credentials.
The estimated CVSS v3.1 score for this vulnerability is 8.1 (High), reflecting a high impact on both confidentiality and integrity. While the attack complexity is elevated due to the requirement of a privileged network position, the consequences of successful interception are severe.
An attacker who successfully executes this Man-in-the-Middle attack gains total visibility into the file server's network stream. This exposes sensitive files served by the application, any authentication credentials passed in HTTP headers, and directory traversal metadata.
Furthermore, the integrity of the data stream is entirely compromised. The attacker intercepts the traffic and possesses the ability to modify HTTP responses in transit. This enables secondary attacks, such as injecting malicious JavaScript into HTML responses or replacing benign downloadable executables with trojanized payloads.
The application operates without indicating a compromise to the end user. The transparent nature of the proxy means the application continues to function normally, creating a false sense of security while data is actively exfiltrated.
The primary remediation for this vulnerability is upgrading goshs to version 2.0.7 or later. The update implements a persistent known_hosts file and a Trust-On-First-Use (TOFU) validation model, aligning the application with standard OpenSSH security practices.
Despite the patch, residual risk remains inherent to the TOFU model. The very first connection established by the patched application remains vulnerable to interception, as the client possesses no prior knowledge of the legitimate host key. Administrators must manually verify the provider's SSH fingerprint against official documentation during the initial connection phase.
Key rotation events by the tunnel provider require operational vigilance. If the provider legitimately changes their host key, goshs will correctly block the connection and raise a HostKeyMismatchError. Users must then manually clear the old entry from ~/.config/goshs/known_hosts. Attackers use these key rotation windows to attempt social engineering, tricking users into accepting a rogue key under the guise of routine maintenance.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
goshs patrickhener | < 2.0.7 | 2.0.7 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-295 (Improper Certificate Validation) |
| Attack Vector | Network (Adjacent/Intercepting) |
| CVSS v3.1 | 8.1 (Estimated) |
| Impact | High (Confidentiality & Integrity via MITM) |
| Exploit Status | None (Unweaponized) |
| KEV Status | Not Listed |
Improper Certificate Validation