✓ProveIt
Examples / Report #3477116 Saved analysis

CVE-2025-15079: libssh global knownhost override

curl · 2025-12-2416.8s analysis · $0.016 in model calls

What the report claims

libcurl's CURLOPT_SSH_KNOWNHOSTS allows a global known_hosts file to be consulted when a host is not found in the user-specified file, potentially accepting unauthorized host identities.

Compare with curl's recorded outcome

Known vulnerability

A real vulnerability: CVE-2025-15079 libssh global known_hosts override

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.

curl policy: Local attackers already present
Why this finding?
  • The curl source code handling CURLOPT_SSH_KNOWNHOSTS was not provided, so the central claim (C1) cannot be verified against the implementation.
  • External sources confirm libssh's fallback to /etc/ssh/ssh_known_hosts when the user file lacks a match (C2).
  • The deterministic check shows SSH_OPTIONS_GLOBAL_KNOWNHOSTS is not referenced in curl's current master, which suggests curl may not set it at all — but this is ambiguous without seeing the actual option-handling code.
  • The report acknowledges the global file is typically not user-writable, limiting exploitability to scenarios where a local attacker can modify /etc/ssh/ssh_known_hosts or where the file already contains malicious entries. This aligns with the project's 'Local attackers already present' policy section.
  • A human reviewer should examine curl's libssh backend code (likely lib/vssh.c) to see whether CURLOPT_SSH_KNOWNHOSTS also sets SSH_OPTIONS_GLOBAL_KNOWNHOSTS to a non-existent path.
What still needs checking
  • curl source file implementing CURLOPT_SSH_KNOWNHOSTS (likely lib/vssh.c or similar) showing how SSH_OPTIONS_KNOWNHOSTS and SSH_OPTIONS_GLOBAL_KNOWNHOSTS are set
How this analysis ran 5 claims · 0 citations verified

Checked against curl master on 2025-12-24 (532d134767df). Dev 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 · 2 references checked out, 1 did not
2 · Claims
NVIDIA-Nemotron-3-Nano-30B-A3B
5 claims · 1769 tokens · $0.0002
3 · Evidence
0 code snippets
real curl source at 532d134767df · 4 docs via Tavily
4 · Judgment
Nemotron-3-Ultra-550b-a55b
9647 tokens · 13.2s · $0.0161
5 · Receipts
0 of 2 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 report. The libssh fallback behavior you describe is documented. However, we need to check curl's libssh backend code to see whether CURLOPT_SSH_KNOWNHOSTS also disables the global knownhosts file (SSH_OPTIONS_GLOBAL_KNOWNHOSTS). Could you confirm which curl source file handles this option, or we will locate it ourselves? Also, note that exploitation typically requires write access to /etc/ssh/ssh_known_hosts, which is a local-privilege scenario.

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

Report claims

C1flaw not verifiable

CURLOPT_SSH_KNOWNHOSTS does not prevent libcurl from using SSH_OPTIONS_GLOBAL_KNOWNHOSTS when the host is not found in the user-specified file

Read the reasoning

The curl source code implementing CURLOPT_SSH_KNOWNHOSTS was not provided. The deterministic check notes SSH_OPTIONS_GLOBAL_KNOWNHOSTS is not found in curl's codebase at the checked revision (532d134767df), but this only indicates curl's source doesn't reference the symbol; it does not confirm whether curl sets or omits this option when CURLOPT_SSH_KNOWNHOSTS is used. Without the relevant curl code (likely in lib/vssh.c or similar), the claim cannot be verified or contradicted.

C2location supported

The flaw occurs when libcurl checks the global known_hosts file at /etc/ssh/ssh_known_hosts if the host is missing from the user file

Read the reasoning

External sources confirm libssh has SSH_OPTIONS_GLOBAL_KNOWNHOSTS with a default of /etc/ssh/ssh_known_hosts, and the knownhosts lookup falls back to the global file when the host is not found in the user file. This describes libssh's documented behavior, not curl's code.

E1:0 E2:454
C3trigger not verifiable

An attacker can cause validation to succeed by providing an empty user knownhosts file and a host name that exists only in the global file

Read the reasoning

This claim depends on C1 being true (that curl doesn't disable the global file). Since C1 is not verifiable without curl's implementation, C3 cannot be assessed.

C4impact not verifiable

Host identity validation succeeds even though the host should not be trusted, leading to potential acceptance of unauthorized keys

Read the reasoning

Impact claim contingent on the flaw existing. Cannot be assessed without verifying C1.

C5reproduction supported

Steps: compile curl with --with-libssh, add a valid entry to /etc/ssh/ssh_known_hosts, clear the user knownhosts file, then run curl --knownhosts knownhosts user@host.example

Read the reasoning

The reproduction steps are internally consistent and plausible assuming the libssh fallback behavior (C2) and the alleged curl omission (C1). They describe a valid test procedure if the flaw exists.

Deterministic checks that failed

  • symbol SSH_OPTIONS_GLOBAL_KNOWNHOSTS exists in other curl releases but not at 532d134767df

What the report says about other projects

confirmed libssh has SSH_OPTIONS_GLOBAL_KNOWNHOSTS that specifies a global known_hosts file used if the host is not found from the file specified in SSH_OPTIONS_KNOWNHOSTS

“SSH_OPTIONS_GLOBAL_KNOWNHOSTS: Set the global known hosts file name (const char *, format string). If the value is NULL, the directory is set to the default global known hosts file, normally /etc/ssh/ssh_known_hosts.” source

Read the original report

Full report on HackerOne ↗

## Summary: libssh has `SSH_OPTIONS_GLOBAL_KNOWNHOSTS` that specifies a global known_hosts file that will be used if the host is not found from the file specified in `SSH_OPTIONS_KNOWNHOSTS` file. libcurl `CURLOPT_SSH_KNOWNHOSTS` doesn't specify an invalid (or `/dev/null`) path to `SSH_OPTIONS_GLOBAL_KNOWNHOSTS` resulting in libcurl accepting any host identities that might be specified in the default file. This is significant when user tries to limit the known hosts to ones specified in their own file, as the global file will be checked if no match is found from the user specified file. By default this file is `/etc/ssh/ssh_known_hosts`, and thus not modifiable by non-privileged user (at least on major platforms). Thus in most situations this issue cannot be exploited by actively modifying the file. This limits the impact of this flaw. ## Affected version 8.17.0 ## Steps To Reproduce: 1. Configure and compile curl with `--with-libssh` 2. Add valid host entry for `host.example` to `/etc/ssh/ssh_known_hosts` 3. `echo "" > knownhosts` 4. `curl --knownhosts knownhosts user@host.example` The host identity validation succeeds even though it should not. ## Remediation - Make `CURLOPT_SSH_KNOWNHOSTS` set `SSH_OPTIONS_GLOBAL_KNOWNHOSTS` to `/dev/null` (or some non-existing path?). ## Supporting Material/References: * https://github.com/libssh/libssh-mirror/blob/ac6d2fad4a8bf07277127736367e90387646363f/src/options.c#L304 * https://github.com/libssh/libssh-mirror/blob/ac6d2fad4a8bf07277127736367e90387646363f/src/knownhosts.c#L1176 ## Impact ## Summary: Host validation unexpectedly succeeding.

Source code

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