Much ado about cURL

cURL is releasing version 8.4.0 on Wednesday, October 11th, 2023 to patch a high-severity issue that is “the worst cURL vulnerability in a while” for both the CLI application and the

Kurt Boberg
October 10th, 2023
Share

We launched Semgrep Supply Chain last fall, with a vision of never seeing a "1644 vulnerable dependencies" alert again. In case you missed that launch: Using Semgrep's static analysis engine, Semgrep Supply Chain filters out over 98% of alerts, leaving you with a manageable list of vulnerabilities to worry about.


Introduction

As you may have heard, cURL released version 8.4.0 on Wednesday, October 11th, 2023, to patch a heap corruption issue in the SOCKS5 handler in both the CLI application and the libcurl C library. The vulnerability has been assigned CVE-2023-38545 and affects libcurl versions 7.69.0 to and including 8.3.0. 

As per the hackerone vulnerability submission, memory corruption occurs if cURL is supplied with a hostname longer than 255 bytes when resolving a SOCKS5 request. If you are reading this, you are probably wondering what Semgrep Supply Chain is doing to help you get a handle on this vulnerability, particularly if you are an existing Semgrep Supply Chain user.

Am I affected?

If you accept arbitrary URLs from untrusted users, do not perform any hostname validation, and pass them to cURL or libcurl using a SOCKS5 proxy configuration, you are affected.

Heap corruption in modern operating systems with memory safety features like Address Space Layout Randomization (ASLR) generally requires additional information disclosure to successfully exploit for code execution. Additionally, per Daniel Stenberg’s writeup, URLs must be valid, so the bytes available to write to the heap are somewhat limited. Initial exploit attempts on vulnerable systems are likely to be crashes due to corrupted heaps.

What is Semgrep Supply Chain doing about cURL?

That depends! While libcurl bindings in libraries are everywhere, many of them bind to your system libcurl and not their own vendored or statically-linked copy. This means that to patch libcurl you most likely need to update your environment rather than install a new version of a library. Semgrep’s research team will continue to investigate and look for statically-linked libcurl in dependencies. Findings for vulnerable versions of libcurl are likely to be “always reachable” rules.

TL;DR

First, update system curl: either your build environment and/or your container image(s).

Managed or interpreted languages will usually prefer linking during package install. pycurl uses curl-config, as does node-libcurl here. Other libraries such as C#’s nac.CurlThin use symlinks to shared libraries.

If you have an asset inventory of your open-source libraries, checking for libcurl is a good follow-up task - any well-documented project should be transparent about how it includes libcurl as a dependency.

Node (JavaScript)

node-libcurl and projects based on it are built at install time with node-gyp and leverage your system libcurl.

In general, if you are using defaults, you need to update system curl.

Python

pycurl uses curl-config to determine which libcurl to link against; however some projects like libcurl-ct use shared libraries.

In general, if you are using defaults, you need to update system curl.

Rust

By default, curl and its derivatives bind to system curl by default. If libcurl is not found, Rust will build it from source. You may optionally specify the libcurl path to link to, but this is not the default behavior.

In general, if you are using defaults, you need to update system curl.

C#

If you’re using libcurl bindings in C# instead of CLR HTTP methods, use nac.CurlThin - it requires manually setting up libcurl but will properly use system curl. Other libraries (CurlThin, libcurl.NET) are out of maintenance and install older versions of curl.

CurlThin installs a vulnerable version (7.69.1), while libcurl.NET installs a version that is too old to be affected (7.13.0). We recommend you deprecate libcurl.NET anyway since it is no longer maintained.

In general, stop using your libcurl library unless it’s nac.CurlThin and update system curl.

Ruby

Gems that use FFI (such as ethon) will use system (or Homebrew) curl due to FFI’s path resolution. This is one of the more popular ways to link native libraries against Ruby. Other methods include curb's automated discovery of libcurl4-openssl-dev and/or explicit build flag with the libcurl version to use. In either case, Ruby is most likely using your system’s version of libcurl.

In general, you need to update system curl.

Go

Go’s C behavior will use the system compiler (and associated linking behavior) when building Go binaries that have C bindings. Unless you have modified your environment, this will usually be system libcurl.

In general, you need to update system curl.

PHP

PHP’s --with-curl option links against system libcurl via pkg-config.

In general, you need to update system curl.

Swift

Community Swift packages that use libcurl generally link against brew-installed curl or libcurl4-openssl-dev installed via your Linux flavor’s package manager.

In general, you need to update system curl.

Summary

Most ecosystems agree - the highest-impact day 0 task you can complete is update curl and libcurl via system package managers. This will give you the largest amount of immediate patch completion and reduce your exposed attack surface the most. If you have the additional resources available, begin a dependency audit to identify which libraries use libcurl and how they link to it.

Try Semgrep Supply Chain for free.

About

Semgrep lets security teams partner with developers and shift left organically, without introducing friction. Semgrep gives security teams confidence that they are only surfacing true, actionable issues to developers, and makes it easy for developers to fix these issues in their existing environments.