Verify SSH host keys in the remote browser (MITM fix) and pin build tarball checksums#4
Open
timc3 wants to merge 2 commits into
Open
Verify SSH host keys in the remote browser (MITM fix) and pin build tarball checksums#4timc3 wants to merge 2 commits into
timc3 wants to merge 2 commits into
Conversation
The libssh2-backed remote browser opened a session and authenticated immediately after the SSH handshake without ever verifying the server's host key. An active network attacker (rogue Wi-Fi, ARP/DNS spoofing, a compromised router) could impersonate the server; in Password auth mode the keyboard-interactive/password callback then sent the user's plaintext password to the impostor. This path had no protection at all, unlike the sshfs mount path which already uses StrictHostKeyChecking=accept-new. Add host-key verification in macfusegui_libssh2_open_session, run after the handshake and before any credentials are sent. The policy mirrors OpenSSH accept-new and shares ~/.ssh/known_hosts with the sshfs path: match connects, a changed key is refused with the offered fingerprint in the error, and an unknown host is trusted on first use and persisted. It fails closed when the host key cannot be read or known_hosts cannot be parsed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
build_libssh2.sh fetched the libssh2 and OpenSSL release tarballs over HTTPS with curl but never verified their integrity, so a compromised mirror or intercepted download could inject malicious code into the statically linked binary. Pin the upstream SHA-256 of each tarball and verify both freshly downloaded and previously cached files, failing the build on any mismatch. The expected hashes can be overridden via the environment for intentional version bumps. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author
|
Ran the full reliability gate locally on
Note: the existing Swift suite drives the browser via a mock |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two hardening changes for the SSH/SFTP attack surface, as two separate commits:
fix:Verify SSH host keys in the remote browser — prevents MITM credential theft (security-critical).build:Pin SHA-256 of the libssh2/OpenSSL source tarballs — build-time supply-chain hardening.1. Host-key verification in the libssh2 remote browser
Problem
macfusegui_libssh2_open_session()inLibSSH2Bridge.cperforms the SSH handshake and then authenticates immediately, with no host-key verification — nolibssh2_session_hostkey()check, noknown_hostscomparison, no fingerprint trust-on-first-use.An active network attacker (rogue Wi-Fi AP, ARP/DNS spoofing, a compromised router/VPN) can impersonate the server. libssh2 completes the handshake against the attacker's key and proceeds to auth. In Password mode the keyboard-interactive/password callback then sends the user's plaintext password to the impostor. Browsing or Test-Connection in Password mode over an untrusted network can therefore leak the password.
There's an asymmetry worth noting: the sshfs mount path already sets
StrictHostKeyChecking=accept-new, so it pins the key on first use. The libssh2 browser path had no equivalent.Fix
Add
macfusegui_verify_host_key(), called right after the handshake and before any credentials are sent. The policy mirrors OpenSSHaccept-newand shares~/.ssh/known_hostswith the sshfs path:known_hostsunparsable /HOMEunset → fail closedThe error propagates through
ensureSessionSync→AppError.remoteBrowserError, so a mismatch surfaces in the browser health banner rather than being swallowed.User-visible behavior change
The browser / Test-Connection will now refuse a server whose host key changed since it was last trusted (e.g. a legitimately rebuilt host). The error tells the user to remove the stale
~/.ssh/known_hostsentry — the same remedy as OpenSSH.2. Checksum pinning for build dependencies
scripts/build_libssh2.shfetched the libssh2 and OpenSSL release tarballs over HTTPS withcurlbut never verified them, so a compromised mirror or intercepted download could inject code into the statically linked binary. This pins the upstream SHA-256 of each tarball and verifies both freshly downloaded and cached files, failing closed on mismatch. Hashes are env-overridable for intentional version bumps.Testing / validation
LibSSH2Bridge.ccompiles clean underclang -fsyntax-only -Wall -Wextra -std=c11against the vendored libssh2 1.11.1 headers (0 warnings); symbol/constant usage was checked against that header.build_libssh2.shpassesbash -n; the pinned hashes match the tarballs inthird_party/src/(and the official upstream release hashes).build.sh+audit_mount_calls.py+ xcodebuild test) locally — please run CI / the gate. The browser is exercised via a mockBrowserTransportin the Swift tests, so this C change isn't covered by existing unit tests.By submitting this PR I agree to license the contribution under GPLv3, per
CONTRIBUTING.md.🤖 Generated with Claude Code