✓ProveIt
Examples / Report #3975408 Saved analysis

CVE-2026-87865: knownhost callback mismatches key as missing

curl · 2026-08-2821.9s analysis · $0.013 in model calls

What the report claims

A mismatched SSH known_hosts entry causes libcurl to treat a missing key as missing instead of mismatched, allowing a hostile server to bypass host verification and authenticate.

Compare with curl's recorded outcome

Known vulnerability

A real vulnerability: CVE-2026-87865 knownhost callback mismatches key as missing

Shown for comparison after analysis. The pipeline did not see this label.

ProveIt's finding

Needs human review

The available evidence does not settle the report. A maintainer should investigate.

Why this finding?
  • No curl source code for lib/vssh/libssh2.c was provided in the context, making all code-dependent claims not_verifiable
  • Deterministic check contradicts the reported line 653 content at the cited revision
  • External sources fetched (CVE-2019-3856, CVE-2019-3857) are unrelated to the claimed CVE-2026-9547
  • Report is detailed with reproduction steps and specific code references, so a human with access to the repository can investigate
What still needs checking
  • The actual source code of lib/vssh/libssh2.c at revision 68720b483728, particularly lines 650-700
  • The libssh2 advisory for CVE-2026-9547 (not the 2019 CVEs that were fetched)
How this analysis ran 6 claims · 0 citations verified

Checked against curl permalink 68720b483728 (68720b483728). Test evaluation split. Citation verification checks that a referenced line was in the evidence; it does not prove the model interpreted it correctly.

1 · Grounding
partially grounded
no model · 6 references checked out, 1 did not
2 · Claims
NVIDIA-Nemotron-3-Nano-30B-A3B
6 claims · 1649 tokens · $0.0002
3 · Evidence
0 code snippets
real curl source at 68720b483728 · 3 docs via Tavily
4 · Judgment
Nemotron-3-Ultra-550b-a55b
7727 tokens · 8.2s · $0.0127
5 · Receipts
0 of 1 citations verified
every citation must point at code the judge was shown
Review a draft reply to the reporter

Edit and verify before sending.

Thank you for the detailed report. The provided context did not include the lib/vssh/libssh2.c source code at the cited revision, and the deterministic check shows line 653 differs from your description. Could you confirm the exact line numbers in the current master branch, or provide the relevant code snippet? Also, the fetched libssh2 advisories cover 2019 CVEs, not CVE-2026-9547 — do you have a link to that advisory?

Inspect all claims and source code 6 claims · 0 code excerpts

Report claims

C1flaw not verifiable

curl treats the first hashed entry whose public name is NULL as the destination and forces that entry's key algorithm without checking its hostname hash

Read the reasoning

The curl source code for lib/vssh/libssh2.c was not provided in the context. The deterministic check shows the file exists at the revision but line 653 reads 'while(!libssh2_knownhost_get(sshc->kh, &store, store)) {' which does not match the callback handling logic described in the claim. Without the actual code around lines 653-687, the claim cannot be verified.

C2location contradicted

lib/vssh/libssh2.c lines 653-687

Read the reasoning

The deterministic check explicitly states that at the cited revision and line 653, the code does not match what the report describes. The report claims lines 653-687 contain the CURLOPT_SSH_KEYFUNCTION callback logic, but the actual line 653 shows a knownhost iteration loop.

deterministic check
C3trigger not verifiable

an unrelated hashed RSA entry before the target's hashed Ed25519 entry

Read the reasoning

Trigger condition depends on the code structure described in C1, which cannot be verified without the source code.

C4impact not verifiable

a hostile RSA server negotiates successfully; libssh2 then filters out the Ed25519 pin and curl passes NOTFOUND to the callback as MISSING

Read the reasoning

Impact claim depends on the code behavior in C1 and C3, which cannot be verified without the source code.

C5reproduction not verifiable

run python3 poc.py --build-dir /absolute/path/to/build --output run.json

Read the reasoning

Reproduction steps are provided but cannot be validated without examining the actual code path they exercise.

C6impact not verifiable

the callback receives MISSING, the hostile server receives the password canary, and libcurl returns ATTACKER_SFTP_BODY

Read the reasoning

Detailed impact claim depends on the vulnerability existing, which cannot be verified without the source code.

Deterministic checks that failed

  • line none of CURLOPT_SSH_KEYFUNCTION, CURLKHMATCH_MISSING, CURLKHMATCH_MISMATCH, json appear near line 653 at 68720b483728; it reads: 'while(!libssh2_knownhost_get(sshc->kh, &store, store)) {'

What the report says about other projects

not addressed CVE-2026-9547 advisory says libssh2 is unaffected

Read the original report

Full report on HackerOne ↗

When libcurl uses libssh2 with a hashed OpenSSH known_hosts file, an unrelated first entry can make a hostile key for an already pinned SFTP/SCP host reach CURLOPT_SSH_KEYFUNCTION as CURLKHMATCH_MISSING instead of CURLKHMATCH_MISMATCH. At https://github.com/curl/curl/blob/68720b4837284335b2d63cb358f8f6ce65f5bc55/lib/vssh/libssh2.c#L653-L687, curl treats the first hashed entry whose public name is NULL as the destination and forces that entry's key algorithm without checking its hostname hash. With an unrelated hashed RSA entry before the target's hashed Ed25519 entry, a hostile RSA server negotiates successfully; libssh2 then filters out the Ed25519 pin and curl passes NOTFOUND to the callback as MISSING. To reproduce on curl 8.21.0 commit 68720b4837284335b2d63cb358f8f6ce65f5bc55, build shared libcurl with `cmake -S . -B build -DCURL_USE_LIBSSH2=ON -DBUILD_SHARED_LIBS=ON`, extract the attachment, and run `python3 poc.py --build-dir /absolute/path/to/build --output run.json`. Both exploit runs exit 0, the callback receives MISSING, the hostile server receives the password canary, and libcurl returns ATTACKER_SFTP_BODY; the target-first and same-type MISMATCH controls send no password. This is a separate libssh2 root from CVE-2026-9547, whose advisory says libssh2 is unaffected; I used AI to assist the source audit and drafting, then personally reran the exact-release, current-master, control, and fixed-control tests. ## Impact A network attacker who controls or intercepts the reached SSH endpoint can make an already pinned host appear genuinely new to a trust-on-first-use callback. Libcurl then authenticates to the hostile endpoint; in the proof, the server receives the configured SSH password and libcurl accepts attacker-controlled SFTP data. The default callback and curl command-line tool are not claimed affected.

Source code

No source code was retrieved for this analysis. The evidence may be incomplete.