In March 2023, a serious vulnerability was identified in libcurl – a core library used by millions of devices, applications, and servers worldwide for secure transfers using URL syntax. This flaw is cataloged as CVE-2023-27537, and it's a textbook example of how small oversights in threading and memory management can cause big security problems.

This write-up will explain what happened, how the exploit works, and provide references and examples in a way that’s simple and straightforward for everyone to understand.

Affected Versions: All libcurl versions before 8...

- Attack Scenario: When multiple threads share HSTS data (HTTP Strict Transport Security) between curl handles, and perform operations at the same time, it can lead to a double free or use-after-free.
- Exploit Impact: Potential denial of service (crash), or possible code execution, depending on environment.
- Fixed in: libcurl 8.. (release notes)

Background: What Are “Handles” and HSTS in libcurl?

- Handles: When you use libcurl to perform transfers, each session is a “handle.” Consider it like a connection or a user session.
- HSTS: HTTP Strict Transport Security tells browsers (or clients) to only talk to certain domains over HTTPS, making them more secure.

In version 7.81., libcurl introduced the ability to share HSTS data (a memory structure tracking HSTS-remembered hosts) between different handles – even across threads, if users tried that.

The Core Bug: Missing Mutex

To speed up transfers, developers often run multiple threads (parallelism). But when you share data between threads, you must synchronize access, typically using mutexes (or locks). If you don’t, both threads can modify or free the same memory at the same time.

In this particular case, the code assumed that HSTS data wouldn’t be shared between threads – but didn’t actually prevent or warn users from doing so. More importantly, it also didn’t apply proper locking around that shared memory.

Where Double Free or Use-After-Free Happens

Imagine two threads, A and B, both with their own curl handles, but *sharing the same HSTS memory*. If both try to clean up (with curl_easy_cleanup or similar), they might:

Or one frees it while the other is still using it (use after free).

This breaks the memory allocator, potentially crashing the process or even opening up arbitrary code execution.

Here’s a conceptual code snippet

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

/* Global shared HSTS storage */
CURLSH *shared_handle;

void* thread_function(void *arg) {
    CURL *handle = curl_easy_init();
    curl_easy_setopt(handle, CURLOPT_SHARE, shared_handle);
    // Perform some transfer
    curl_easy_perform(handle);

    /* Potentially dangerous! Both threads may cleanup shared HSTS */
    curl_easy_cleanup(handle);

    return NULL;
}

int main(void) {
    curl_global_init(CURL_GLOBAL_ALL);

    shared_handle = curl_share_init();
    curl_share_setopt(shared_handle, CURLSHOPT_SHARE, CURL_LOCK_DATA_HSTS);

    pthread_t t1, t2;
    pthread_create(&t1, NULL, thread_function, NULL);
    pthread_create(&t2, NULL, thread_function, NULL);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    curl_share_cleanup(shared_handle);
    curl_global_cleanup();
    return ;
}


In the buggy versions, both threads may manipulate or free the same HSTS data structure at nearly the same time – causing the vulnerability.

How the Exploit Can Happen

While the crash is straightforward (just two destructors running together), actual code execution is trickier but possible if the program’s memory layout is predictable or if heap metadata corruption can be spun into code control.

If the application then writes to this memory, arbitrary code execution might happen.

This would, however, require a local attacker or malicious code running in the same process as the user of libcurl.

libcurl 8.. introduced proper locking and clarified documentation

- Now, CURL_LOCK_DATA_HSTS cannot be safely shared between threads unless the application uses appropriate locking.

Always ensure that if you are sharing data between threads, you implement correct mutexes yourself!

If you use libcurl and multi-threading, always upgrade to 8.. or later and review your thread safety.

Official Advisory:

curl security advisory: CVE-2023-27537 (Double free HSTS data)

Fix Commit:

GitHub Fix PR for HSTS double free problem

Common Vulnerabilities and Exposures (CVE) Entry:

NVD Details for CVE-2023-27537

libcurl Thread Safety Docs:

Thread Safety in libcurl

Summary Table

| Thing to Check           | Is It Affected?                  |
|------------------------- | ---------------------------------|
| libcurl version <8..   | Vulnerable                       |
| libcurl version >=8..  | Not vulnerable (patched)         |
| HSTS (CURL_LOCK_DATA_HSTS) used with threads | Vulnerable |
| Used mutex/locking?      | Safer (if implemented by user)   |

Avoid sharing handles or shared objects between threads unless you *really* understand the risks.

This one-line mistake in memory concurrency could take down your server in a flash, so always remember: Lock what you share across threads, or don’t share at all!

Timeline

Published on: 03/30/2023 20:15:00 UTC
Last modified on: 04/20/2023 09:15:00 UTC