All posts

Reproducing DEBIAN-CVE-2026-94266 (curl effective-URL credential leak)

curl / libcurl

Versions
Version typeVulnerableFixed
Releases7.62.0 - 8.22.08.23.0
Tested builds8.23.0-DEV8.23.1-DEV
Status
Catalog
Fixed in fork
Fork branchMerged
SeverityLowUpdated
Related links
Advisory
Official advisoryOSV recordCatalog record
Fixes
Upstream fixFork mergeFork branch
Code
Vulnerable sourceFixed sourceFork repository
Discussion
Original report and discussion

Setup

curl exposes netrc credentials in CURLINFO_EFFECTIVE_URL after a relative redirect.

Vulnerableupstream at aad438d, reports 8.23.0-DEV
Fixedour fork at ce57339, reports 8.23.1-DEV
Buildsame flags both sides
Sandboxno network, loopback only

lib/url.c merges the netrc login into the URL handle. When Curl_http_follow re-parses a relative redirect into the same handle, stale userinfo remains in CURLINFO_EFFECTIVE_URL. Upstream fix 7a6bd027, included in the fork, strips the user and password in a new effective_url() before returning the value.

A loopback server answers /r1 with a 301 redirect to relative Location /r2. The client authenticates with a netrc file, follows the redirect, and prints %{url_effective}. If the value contains user:pass, the credentials leaked into the reported URL.

Reproduce (vulnerable build)

Command
docker run --rm --network none --pids-limit 64 --memory 512m --read-only --tmpfs /tmp:rw,noexec,nosuid,size=64m cve-94266-demo python3 /task/repro.py /opt/tree-vuln/bin/curl
Output
$ LD_LIBRARY_PATH=/opt/tree-vuln/lib /opt/tree-vuln/bin/curl --version | head -1
curl 8.23.0-DEV (x86_64-pc-linux-gnu) libcurl/8.23.0-DEV OpenSSL/3.5.7
$ LD_LIBRARY_PATH=/opt/tree-vuln/lib /opt/tree-vuln/bin/curl --netrc-optional --netrc-file /tmp/netrc94266 -L --max-time 20 -w EFFECTIVE_URL=%{url_effective}
 -o /dev/null http://127.0.0.1:8000/r1
--- exit: 0
--- stdout:
EFFECTIVE_URL=http://netrcuser:netrcSECRET123@127.0.0.1:8000/r2
--- server Authorization headers seen:
req1: Basic bmV0cmN1c2VyOm5ldHJjU0VDUk...
req2: Basic bmV0cmN1c2VyOm5ldHJjU0VDUk...
RED - netrc password present in effective URL

Regression test 5032 shows credentials in the effective URL.

Command
docker run --rm --network none --pids-limit 64 --memory 1g cve-94266-demo sh -c 'cp /src/fixed/tests/data/test5032 /src/vuln/tests/data/test5032 && cd /src/vuln && make -C tests/server >/tmp/srv.log 2>&1 && cd tests && perl runtests.pl 5032 2>&1 | tail -n 20'
Output
Warning: test5032 not present in tests/data/Makefile.am
test 5032 [CVE-2026-94266 effective URL has no netrc credentials after redirect]

 5032: stdout FAILED:
--- log/check-expected
+++ log/check-generated
@@ -1 +1 @@
-EFFECTIVE_URL=http://127.0.0.1:36705/50320002[LF]
+EFFECTIVE_URL=http://netrcuser:netrcSECRET123@127.0.0.1:36705/50320002[LF]

 - abort tests
TESTDONE: 1 tests were considered during 1 seconds.
TESTDONE: 0 tests out of 1 reported OK: 0%

FAIL 5032: 'CVE-2026-94266 effective URL has no netrc credentials after redirect' netrc, CURLINFO_EFFECTIVE_URL

Verify (fork-fixed build)

Run the same repro against the fork build.

Command
docker run --rm --network none --pids-limit 64 --memory 512m --read-only --tmpfs /tmp:rw,noexec,nosuid,size=64m cve-94266-demo python3 /task/repro.py /opt/tree-fixed/bin/curl
Output
$ LD_LIBRARY_PATH=/opt/tree-fixed/lib /opt/tree-fixed/bin/curl --version | head -1
curl 8.23.1-DEV (x86_64-pc-linux-gnu) libcurl/8.23.1-DEV OpenSSL/3.5.7
$ LD_LIBRARY_PATH=/opt/tree-fixed/lib /opt/tree-fixed/bin/curl --netrc-optional --netrc-file /tmp/netrc94266 -L --max-time 20 -w EFFECTIVE_URL=%{url_effective}
 -o /dev/null http://127.0.0.1:8000/r1
--- exit: 0
--- stdout:
EFFECTIVE_URL=http://127.0.0.1:8000/r2
--- server Authorization headers seen:
req1: Basic bmV0cmN1c2VyOm5ldHJjU0VDUk...
req2: Basic bmV0cmN1c2VyOm5ldHJjU0VDUk...
GREEN - effective URL has no credentials

The redirect still completes (exit 0, both requests authenticated). The effective URL no longer contains credentials.

The regression test passes on the fixed tree.

Command
docker run --rm --network none --pids-limit 64 --memory 1g cve-94266-demo sh -c 'cd /src/fixed && make -C tests/server >/tmp/srv.log 2>&1 && cd tests && perl runtests.pl 5032 2>&1 | tail -n 6'
Output
test 5032 [CVE-2026-94266 effective URL has no netrc credentials after redirect]
s-p----e--- OK (1   out of 1  , remaining: 00:00, took 1.068s, duration: 00:01)
TESTDONE: 1 tests were considered during 1 seconds.
TESTDONE: 1 tests out of 1 reported OK: 100%

Limits

Trigger is netrc credentials plus a redirect that merges into the base URL (a relative Location, as in upstream test 1876). An absolute Location with no userinfo resets the handle and stays clean even unfixed. Wire traffic is identical either way: both requests carry the normal Authorization header.

Attack flow

Client reads netrc credentials for 127.0.0.1
Server answers 301 with relative Location /r2
curl merges Location into the handle, keeps stale userinfo
Vulnerable: url_effective contains user:pass (RED)
Fixed: effective_url() strips credentials, wire traffic unchanged (GREEN)

Agent runbook

Agent runbook - run in order
docker run --rm --network none --pids-limit 64 --memory 512m --read-only --tmpfs /tmp:rw,noexec,nosuid,size=64m cve-94266-demo python3 /task/repro.py /opt/tree-vuln/bin/curl
docker run --rm --network none --pids-limit 64 --memory 1g cve-94266-demo sh -c 'cp /src/fixed/tests/data/test5032 /src/vuln/tests/data/test5032 && cd /src/vuln && make -C tests/server >/tmp/srv.log 2>&1 && cd tests && perl runtests.pl 5032 2>&1 | tail -n 20'
docker run --rm --network none --pids-limit 64 --memory 512m --read-only --tmpfs /tmp:rw,noexec,nosuid,size=64m cve-94266-demo python3 /task/repro.py /opt/tree-fixed/bin/curl
docker run --rm --network none --pids-limit 64 --memory 1g cve-94266-demo sh -c 'cd /src/fixed && make -C tests/server >/tmp/srv.log 2>&1 && cd tests && perl runtests.pl 5032 2>&1 | tail -n 6'

Release information

SourceOfficial advisory
Checked
SeverityLow
WeaknessCWE-522
Other fixed branches
  • 8.20.x from 8.20.2
  • 8.16.x from 8.16.2
  • 8.14.x from 8.14.3

Recorded evidence

upstream fix 7a6bd027 present in fork base
regression test tests/data/test5032 executed RED then GREEN

Status history

DateStatusRecord
In progressfix agent dispatched
Fixed in forkmerged to fork master a33880b