✓ProveIt
Examples / Report #1040166 Saved analysis

CVE-2020-8284: trusting FTP PASV responses

curl · 2020-11-2114.4s analysis · $0.011 in model calls

What the report claims

curl trusts FTP PASV responses when CURLOPT_FTP_SKIP_PASV_IP is disabled, allowing an attacker to force curl to perform port scanning on behalf of the server.

Compare with curl's recorded outcome

Known vulnerability

A real vulnerability: CVE-2020-8284 trusting FTP PASV responses

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?
  • The provided code snippets only show curl_easy_perform in lib/easy.c, not the FTP PASV handling logic that would decide the claims.
  • The deterministic checks confirm CURLOPT_FTP_SKIP_PASV_IP exists but do not show its default value or how the PASV response is processed.
  • The report describes a plausible attack (CVE-2020-8284) but verification requires examining lib/ftp.c or similar, which is not in the provided context.
What still needs checking
  • The FTP PASV response parsing and connection logic (likely in lib/ftp.c) to see if the IP/port from the PASV response is used without validation when CURLOPT_FTP_SKIP_PASV_IP is disabled.
  • The default value of CURLOPT_FTP_SKIP_PASV_IP at the reported revision.
How this analysis ran 5 claims · 0 citations verified

Checked against curl master on 2020-11-21 (0d16a49c16a8). 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
grounded
no model · 1 references checked out, 0 did not
2 · Claims
NVIDIA-Nemotron-3-Nano-30B-A3B
5 claims · 1719 tokens · $0.0002
3 · Evidence
1 code snippets
real curl source at 0d16a49c16a8 · 3 docs via Tavily
4 · Judgment
Nemotron-3-Ultra-550b-a55b
5609 tokens · 11.6s · $0.0111
5 · Receipts
0 of 0 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 code snippets for triage do not include the FTP PASV handling logic (likely in lib/ftp.c). We will examine that code to verify whether curl connects to the PASV-provided IP/port without validation when CURLOPT_FTP_SKIP_PASV_IP is disabled. Please confirm the exact curl version/commit tested (you referenced 0d16a49c16a8).

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

Report claims

C1flaw not verifiable

curl trusts FTP PASV responses when CURLOPT_FTP_SKIP_PASV_IP is disabled

Read the reasoning

The FTP PASV handling code (likely in lib/ftp.c) is not provided in the source snippets. Cannot verify if curl trusts PASV responses when CURLOPT_FTP_SKIP_PASV_IP is disabled.

C2location not verifiable

in libcurl's FTP PASV handling code

Read the reasoning

Location claim references curl_ftp.c but that file is not provided.

C3trigger not verifiable

by controlling the URL used by curl and sending a PASV response with attacker‑controlled IP and port

Read the reasoning

Trigger mechanism depends on FTP PASV parsing code not provided.

C4impact not verifiable

enables port scanning of internal services and potential information disclosure

Read the reasoning

Impact claim relies on the flaw being present; cannot verify without the handling code.

C5reproduction not verifiable

use a malicious FTP server that returns a PASV response containing the target IP and port

Read the reasoning

Reproduction steps reference an attachment not available; the malicious FTP server behavior cannot be verified against curl code.

Read the original report

Full report on HackerOne ↗

## Summary: The issue here arises from the fact that curl by default has the option CURLOPT_FTP_SKIP_PASV_IP disabled by default. As a result, an attacker controlling the URL used by curl, can perform port scanning on behalf of the server where curl is running. This can be achieved by setting up a custom FTP server that would setup the data channel through the PASV command using the port scanning target IP and port in the PASV connection info. One good target for this issue are web applications vulnerable to SSRF. ## Steps To Reproduce: So we can differentiate between open, closed and filtered ports with the following: 1. Open ports curl will reply with TYPE after the PASV command example: Received: USER anonymous in 5 Received: PASS ftp@example.com in 5 Received: PWD in 5ms Received: EPSV in 6ms Received: PASV in 6ms **Received: TYPE I in 6ms** Received: SIZE whatever in 5ms Received: RETR whatever in 5ms 2. Filtered curl will timeout after the PASV command example: Received: USER anonymous in 6 Received: PASS ftp@example.com in 5 Received: PWD in 5ms Received: EPSV in 6ms Received: PASV in 5ms Received: in **1011ms** 3. Closed curl will close the control channel connection immediately after PASV example: Received: USER anonymous in 6ms Received: PASS ftp@example.com in 6ms Received: PWD in 5ms Received: EPSV in 5ms Received: PASV in 5ms Received: in **5ms** In the attachments, I have included an ftp server (F1088885) that automates these steps. Usage: ./ssrf_pasvaggresvftp.sh -t 127.0.0.1/31 -p 80,8000-8100 -x ./ftp_curl.sh -vv the file included in the -x option is supposed to trigger the ssrf on the target server that would lead to the call of curl with the attacker's URL. In this case we simulate the issue by calling curl locally. The attachment F1088859 is the script used in the example. ## Impact Through the port scanning, an attacker could uncover services running in the internal network. It could also be possible to perform version enumeration or other information disclosure if the attacker can get back the results of curl. For example, an attacker points curl at host:22 for the data channel . If an ssh server is running on that host, then it will reply with its version which is then disclosed to the attacker. Ultimately, this issue can be used as a stepping stone to launch further attacks on the vulnerable server.

Source code

lib/easy.clines 700–703 · definition of curl_easy_perform
700CURLcode curl_easy_perform(struct Curl_easy *data)
701{
702 return easy_perform(data, FALSE);
703}