# Squid leaks previous content from reusable buffer

Malicious FTP listing with tab-separated tokens makes Squid's ftpListParseParts miscalculate name offset, leaking pooled memory including other users' requests/responses.

- Payout: hidden
- Severity: high
- Program: Internet Bug Bounty
- Found by: jeriko_one
- Disclosed: 2021-08-26
- CVE: CVE-2019-12528
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/824163
- Library page: https://bugbountylibrary.com/r/h1%3A824163
- Tags: area:cloud domain:infra impact:data-leak impact:pii-leak kind:bounty platform:hackerone sev:high tech:linux technique:source-review vuln:info-disclosure vuln:memory-corruption

**Target:** Squid FTP gateway listing parser (FtpGateway.cc)
**Root cause:** ftpListParseParts assumes tokens are space-separated in the original line; a tab delimiter makes strstr match tokens[3] instead of tokens[2], and incrementing by strlen(tokens[2])+2 pushes ct past the NUL terminator.
**Steps:**
1. Start Squid: `./sbin/squid`
2. Run malicious FTP server: `./squid_leak.py 8080`
3. Request via proxy: `printf "GET ftp://<ftp ip>:8080/ HTTP/1.1\r\n\r\n" | nc <squid hostname> 3128`
4. FTP server returns listing line like `04-05-70 09:33PM\tA*126 A*126`
5. Observe leaked memory in returned HTML under the Parent Directory row
**How found:** Code review of Ftp::Gateway::parsingListing and ftpListParseParts; noticed memAllocate(MEM_4K_BUF) buffers are pooled and not zeroed, and that strtok delimiters (w_space includes tab) differ from the space-based strstr reconstruction, then confirmed with gdb that ct lands past the NUL.
**Exploitation:** Attacker controls an FTP server; when a victim (or the attacker) fetches a directory listing through Squid, the crafted listing causes p->name to point past the line's NUL into the MEM_4K_BUF pool buffer, which is never zeroed on reuse, so prior request/response data is rendered into the HTML listing returned to the attacker.
**Insight:** When a parser tokenizes with a delimiter set (e.g. tab+space) but later reconstructs a substring assuming a single delimiter, a tab in the input shifts the match to the wrong token; combined with pooled non-zeroed buffers, the off-by-N read becomes an info leak.
