Safeguard
Supply Chain Security•

curl Release History: httpget to curl 8, TLS Backends and Security

curl began as HttpGet in 1996, became curl 4.0 in March 1998 and reached 8.23.0 in October 2026. Every era, TLS backend, removal and security rule explained.

Safeguard Security Team
41 min read

curl started life as HttpGet, a small command line tool released by Rafael Sagula on 11 November 1996, which Daniel Stenberg extended and then took over as maintainer. It was renamed urlget in August 1997 and became curl 4.0 on 20 March 1998. The library, libcurl, arrived with 7.1 in August 2000, and curl 8.0.0 shipped on 20 March 2023, exactly 25 years after curl 4.0. As of 25 October 2026 the latest release is 8.23.0 (14 October 2026), the next is planned for 9 December 2026, and the project ships a release every eight weeks.

Key takeaways

  • HttpGet 0.1 dates to 11 November 1996, urlget 2.0 to August 1997 and curl 4.0 to 20 March 1998. Version numbers carried over, so curl never had a 1.0.
  • libcurl's first non beta release was 7.1 (7 August 2000). Certificate verification became the default in 7.10 (1 October 2002), so -k in a script switches off a 24 year old protection.
  • curl 8.0.0 (20 March 2023) listed one change: no more platforms with a curl_off_t smaller than 8 bytes. The 8.x series is mostly removal: NSS, gskit, hyper, BearSSL, Secure Transport, msh3, OpenSSL 1.1.1 and older, OpenSSL-QUIC, RTMP, TLS-SRP and SMB.
  • Releases ship every 8 weeks on Wednesdays. Only the latest release gets fixes; older versions are patched by distributions through backports.
  • Security issues are rated Low, Medium, High or Critical without CVSS. curl is its own CVE Numbering Authority, and its CVE page listed 239 vulnerabilities on 25 October 2026.
  • The bug bounty ran from 2018 until the end of January 2026. Reporters must now disclose AI use, and users who submit made up reports are banned.

How did curl begin, and who maintains it?

The curl history page tells the story in the project's own words. Towards the end of 1996 Daniel Stenberg was writing an IRC bot and wanted to fetch currency exchange rates from the web. On 11 November 1996 a Brazilian developer, Rafael Sagula, released HttpGet 0.1. Daniel extended it, his additions shipped as HttpGet 0.2 on 17 December 1996, and he soon became the maintainer.

The tool grew fast: HTTP proxy support in HttpGet 1.0 (8 April 1997), then Gopher and FTP downloads, which prompted the rename to urlget 2.0 in August 1997. Windows and Solaris builds, FTP upload and HTTP POST followed in the 2.x and 3.x releases, and urlget 3.12 (14 March 1998) added proxy authentication.

With uploads in place the name "urlget" was misleading again. On 20 March 1998 the project released curl 4.0. The changelog entry for 4.0 explains that there were already too many programs called urlget, and that the tool could now do a lot more than fetch URLs. The version number kept counting from the urlget days, which is why the first release called curl is version 4.

Who runs the project today?

The governance page describes curl as a BDFL (benevolent dictator for life) style project with Daniel Stenberg as the driving force. It is candid that this setup exists for convenience and because it has worked, not because anyone thinks it is a superior model. Points from that page that matter to anyone who depends on curl:

  • No legal entity. The project is not part of any foundation or country; copyright stays with the people and organisations who wrote the code.
  • Decisions aim for consensus; failing that, a maintainer who knows the area decides. Maintainers are the people with push access, removed when inactive.
  • A small security team, the members of the private curl security list.
  • No commercial support from the project. The page states that Daniel works for a company that offers it; the history page dates his full time work on curl to January 2019.

For a dependency this widespread, the written policies, not any contract, are what you plan around.

curl release timeline: the milestones that mattered

The table below draws on the history page, the changelog and the deprecation page on curl.se. Dates are as the project records them.

DateRelease or eventWhat changed
11 Nov 1996HttpGet 0.1Rafael Sagula's original tool
17 Dec 1996HttpGet 0.2First release with Daniel Stenberg's additions
8 Apr 1997HttpGet 1.0HTTP proxy support
Aug 1997urlget 2.0Renamed after FTP download support was added
20 Mar 1998curl 4.0Renamed curl; first release under the curl name
1998curl 4.xSSL support added using SSLeay; licence moved from GPL to MPL with 4.9
7 Aug 2000curl 7.1First non beta libcurl with the easy interface
Jan 2001curl 7.5.2Licence becomes MIT or MPL
22 Mar 2001curl 7.7HTTP 1.1 and persistent connections; first experimental ftps
1 Oct 2002curl 7.10MIT only; peer certificate verification on by default
Apr 2005GnuTLS available as a TLS backend; multi_socket API
Sep 2006libcurl SONAME bumped to 4
Feb 2007NSS TLS backend added
Dec 2009IMAP, POP3 and SMTP support
Jul 2012Schannel (Windows) and Darwin SSL (Apple) TLS backends
14 Oct 20137.33.0First HTTP/2 work with nghttp2; krb4 removed
Mar 2014First real release supporting HTTP/2
27 Jan 20167.47.0curl tool uses HTTP/2 for HTTPS URLs by default
21 Dec 20167.52.0HTTPS proxy support; first TLS 1.3 support
Jul 2017Continuous fuzzing of libcurl begins under OSS-Fuzz
31 Oct 20187.62.0DNS over HTTPS, URL API, multiplexing on by default
Dec 20187.63.0axTLS removed
11 Sep 20197.66.0First (experimental) HTTP/3; parallel transfers with -Z
Mar 20207.69.0PolarSSL removed
31 Mar 20217.76.0rustls backend added
Mar 20227.82.0--json added; MesaLink removed
Oct 20227.86.0Initial WebSocket support; NPN removed
20 Mar 20238.0.0Drops platforms without a 64 bit curl_off_t
Dec 20238.5.0HTTP/3 with ngtcp2 no longer experimental
22 May 20248.8.0NTLM_WB removed; experimental ECH
6 Nov 20248.11.0TLS 1.3 early data; WebSocket no longer experimental
5 Nov 20258.17.0winbuild build system removed; Apple SecTrust support
29 Apr 20268.20.0RTMP removed; NTLM and SMB become opt in
24 Jun 20268.21.0HTTP/3 proxy CONNECT and MASQUE CONNECT-UDP (ngtcp2)
2 Sep 20268.22.0TLS-SRP removed; RFC 9421 HTTP Message Signatures
14 Oct 20268.23.0SMB support removed
9 Dec 20268.24.0 (planned)Next scheduled release

The early curl years: names, licences and SSL (1998 to 1999)

The first year under the curl name set several patterns that still hold. SSL support arrived in 1998, powered by Eric Young's SSLeay library, and moved to OpenSSL when that project took over from SSLeay in early 1999. That was curl's first TLS backend and it remains the most feature complete one today.

Licensing moved several times. The history page records that the curl 4.9 release in October 1998, which also introduced cookie support, moved curl off the GPL to the MPL "to restrict the effects of copyleft" when the code base was around 4,000 lines. In January 2001 curl 7.5.2 became available under MIT or MPL, which ended complaints from GPL projects that could not link an MPL only library. With 7.10 on 1 October 2002 curl became MIT only. The changelog for 7.10 says it bluntly: no more dual licensing. Today the copyright page calls it the curl license, a text "inspired by MIT/X" with its own SPDX identifier, and the verify page says every file in the repository carries a clear copyright and licence statement.

Other early firsts: the -F multipart form option and Telnet in November 1998, the first man page with curl 5 in December 1998, LDAP and file:// in 1999, and curl 6.0 in September 1999 at about 15,000 lines of code.

curl 7 and the birth of libcurl (2000 to 2023)

curl 7 lasted almost 23 years, from 7.1 in August 2000 to 7.88.1 in February 2023. Its defining change was the library. In spring 2000 the project did a major internal overhaul to expose a library interface, and 7.1 (7 August 2000) shipped the first non beta "easy" interface. That decision is the reason curl ended up everywhere: programs could now link libcurl instead of shelling out to a binary.

PHP adopted libcurl in the same month, and it has been a supported PHP module since PHP 4.0.2. By the time the history page was written, more than 16 language bindings existed; the 2010 snapshot on the same page counts 39 known bindings.

Certificate verification by default

The most important security default in curl's history came with 7.10 on 1 October 2002. The changelog says libcurl now does peer certificate verification by default and that this "needs to be disabled if you need to talk to SSL servers in an insecure way", pointing at -k. Every TLS connection curl has made since then has checked the server certificate unless someone turned that off. That is why -k and --insecure in scripts deserve attention: they are not a minor convenience flag, they remove the one control that stops a machine in the middle from impersonating the server.

The project also started offering the Mozilla CA certificate bundle as a PEM file on its website in October 2006, which is still available from the CA extract page for systems that need a bundle.

SONAME bumps and the stable ABI

libcurl's shared library version tells a story of its own. The history page records the major SONAME being set to 1 in November 2000, bumped to 2 with 7.7 in March 2001 (the HTTP 1.1 and persistent connection overhaul), to 3 with 7.12.0 in June 2004 (removal of curl_formparse()), and to 4 in September 2006 when FTP third party transfer support was removed. It has stayed at 4 since. That matters for inventory: a libcurl.so.4 file on a system tells you the ABI generation, not the version, and could be anything from a 2006 build to last week's release.

Protocols added and removed

curl 7 kept adding protocols: TFTP (2005), SCP and SFTP (2006), IMAP, POP3 and SMTP (2009), RTSP and RTMP (2010), SMB (2014), MQTT (2020) and WebSocket (2022). It also removed some. Gopher was dropped in January 2006 after the team found long standing bugs and concluded nobody used it (it returned in 2010), Kerberos 4 went in October 2013, and HTTP pipelining in 7.65.0.

HTTP/2, TLS 1.3 and HTTP/3

curl's work on newer HTTP versions spans a decade:

  • HTTP/2. The first steps using the nghttp2 library came in September 2013 (7.33.0), with the first real release supporting HTTP/2 in March 2014. Multiplexing arrived in June 2015 and server push in August 2015. In January 2016 (7.47.0) the curl tool started using HTTP/2 for HTTPS URLs by default, and in October 2018 (7.62.0) libcurl did the same and turned multiplexing on by default.
  • TLS 1.3. First support came in 7.52.0 on 21 December 2016, with the --tlsv1.3 option. TLS 1.3 early data followed in November 2024.
  • HTTPS proxies. Also 7.52.0, December 2016.
  • HTTP/3 and QUIC. The first HTTP/3 requests with curl happened in August 2019, and 7.66.0 (11 September 2019) listed initial HTTP/3 support as experimental and not yet working. Alt-Svc support, experimental from March 2019, is listed on the history page as supported in December 2020. HTTP/3 using the ngtcp2 library stopped being experimental in December 2023. The current HTTP/3 page lists ngtcp2 as the supported QUIC library and quiche as still experimental.

What changed in curl 8.0?

Less than the number suggests. curl 8.0.0 shipped on 20 March 2023, the 25th anniversary of curl 4.0. The 8.0.0 changelog lists exactly one change: the build no longer supports systems where curl_off_t is smaller than 8 bytes. Everything else in that release was bug fixes. The release table shows 8.0.1 on the same day, a one fix follow up.

The version numbering page explains why that is enough for a major bump. The main number moves for "really big, world colliding changes", the middle number when features are added, and the last number for bug fixes only. Dropping every platform without 64 bit file offsets qualified. For application developers the libcurl API and ABI stayed compatible, so code written against 7.x continued to build against 8.0.

The real story of the 8.x series is what came after.

The 8.x series: what curl removed and why

The deprecation page lists items scheduled for removal, asks anyone affected to write to the curl-library mailing list, and keeps a list of past removals with the version that removed each one. Read together with the changelog, the pattern in 8.x is a steady cut of old backends, old platforms and rarely used protocols.

Removed or changedVersionRelease date
Support for systems without 64 bit data types8.0.020 Mar 2023
NSS TLS backend8.3.013 Sep 2023
gskit TLS backend8.3.013 Sep 2023
MinGW v18.4.011 Oct 2023
NTLM_WB8.8.022 May 2024
Space separated NOPROXY patterns8.9.024 Jul 2024
hyper HTTP backend8.12.05 Feb 2025
Visual Studio 2005 and older8.13.02 Apr 2025
Secure Transport (Apple) TLS backend8.15.016 Jul 2025
BearSSL TLS backend8.15.016 Jul 2025
msh3 HTTP/3 backend8.16.010 Sep 2025
winbuild build system8.17.05 Nov 2025
Windows CE, Visual Studio 20088.18.07 Jan 2026
OpenSSL 1.1.1 and older8.18.07 Jan 2026
Windows XP8.19.011 Mar 2026
OpenSSL-QUIC8.19.011 Mar 2026
CMake 3.17 and older, c-ares older than 1.16.08.20.029 Apr 2026
RTMP8.20.029 Apr 2026
SMB and NTLM become opt in8.20.029 Apr 2026
TLS-SRP8.22.02 Sep 2026
SMB8.23.014 Oct 2026

The deprecation page also lists what is coming. As of 25 October 2026 it says:

  • NTLM authentication is to be removed. The page gives September 2026 as the removal date; NTLM became opt in with 8.20.0 and 8.22.0 blocked NTLM fallback inside SPNEGO negotiation, but the past removals list does not yet show NTLM as removed.
  • Local crypto implementations (curl's own bundled MD4, MD5 and SHA256 code for builds without a TLS library) are to be removed in October 2026. The page warns that this disables some functions, for example Digest authentication, in builds without TLS.
  • HTTP/2 server push is to be removed in March 2027. It was never supported by the command line tool, only by libcurl.
  • Common Name matching in certificates for the OpenSSL backend (and its forks) is to be removed in the release after 8.23.0. The page notes that browsers stopped supporting the CN field for host matching in 2012 and that RFC 9525 removed it.

The lesson: curl announces removals months ahead on the deprecation page. If you build curl yourself, a backend you chose years ago may stop compiling on upgrade. That is the moment to switch, not to pin.

TLS backends and protocol support by version

curl has always separated the transfer logic from the TLS library underneath. That design let it run on every platform, but it also means the security properties of a curl build depend on which backend it was built with. The table below tracks every TLS backend the history and deprecation pages mention.

TLS backendAddedRemovedNotes
SSLeay19981999Replaced by OpenSSL when SSLeay was abandoned
OpenSSL (and forks such as LibreSSL, BoringSSL, AWS-LC, quictls)1999Still supportedOpenSSL 1.1.1 and older removed in 8.18.0
GnuTLSApr 2005Still supported
NSSFeb 20078.3.0 (Sep 2023)
PolarSSL20107.69.0 (Mar 2020)Succeeded by mbedTLS
axTLSFeb 20117.63.0 (Dec 2018)
CyaSSL, later wolfSSLApr 2011Still supported
Schannel (Windows native)Jul 2012Still supported
Darwin SSL, later Secure Transport (Apple native)Jul 20128.15.0 (Jul 2025)Apple SecTrust native CA support added Nov 2025
gskitnot dated on the history page8.3.0 (Sep 2023)
MesaLinkOct 2018 (7.62.0)Mar 2022
BearSSLJan 20208.15.0 (Jul 2025)
rustls7.76.0 (Mar 2021)Still listedThe comparison page marks it "no" under Supported, meaning still experimental
mbedTLSnot dated on the history pageStill supported

The "SSL libraries compared" page, which covers only libraries libcurl can still be built with, lists OpenSSL, GnuTLS, wolfSSL, mbedTLS, Schannel and rustls. All six support TLS 1.2 and TLS 1.3 and ALPN. rustls is the only one that does not offer TLS 1.0 or 1.1. Only the OpenSSL column shows a QUIC implementation; the page notes that OpenSSL 3.5 and later and the OpenSSL forks offer the QUIC API that curl uses with ngtcp2, and the HTTP/3 page says OpenSSL 3.5.0 and later needs ngtcp2 1.12.0 or later. Note one inconsistency on that page: it still lists TLS SRP as available with OpenSSL and GnuTLS, while the changelog and deprecation page say TLS-SRP was dropped in 8.22.0. The changelog is the more recent and specific record.

HTTP backends and HTTP/3 stacks

TLS is not the only pluggable layer. 7.75.0 (3 February 2021) added hyper as an alternative HTTP backend written in Rust; it was removed in 8.12.0 (February 2025). For HTTP/3, curl has used ngtcp2 with nghttp3, quiche, and msh3. msh3 was added in April 2022 and removed in 8.16.0. OpenSSL's own QUIC stack was usable experimentally and then removed as a curl backend in 8.19.0. As of October 2026 ngtcp2 is the only non experimental HTTP/3 stack.

Why backend choice is a security decision

The comparison page also shows which backends use the platform's native certificate store, which handle revocation lists automatically (only Schannel) and which offer FIPS 140 support. A build on a backend removed upstream is on a code path the project no longer tests or patches.

How does the curl release cadence work?

The release procedure page sets out the schedule. curl normally releases every 8 weeks, on Wednesdays. Each 56 day cycle has three periods:

PeriodLengthWhat gets merged
Cool downFirst 10 days after a releaseBug fixes only; a regression may trigger a patch release
Feature windowNext 21 daysNew features and changes; any accepted feature bumps the minor number
Feature freezeFinal 25 daysBug fixes and polish only

Three release candidates ship during the freeze, 25, 16 and 7 days before release. The page says they are for testing only, never production.

A release can move by a full week if it would land on a holiday or when the release manager is unavailable, and the project can break the cycle for a patch release "if a critical enough problem is reported". The page lists the coming dates as 9 December 2026, 3 February 2027, 31 March 2027, 26 May 2027, 21 July 2027 and 15 September 2027.

How are patch releases handled?

There are no long lived maintenance branches. A patch release is the next number on the same line, cut from master after a regression or serious problem. The release table shows them landing between the same day (8.0.1, 8.7.1) and five weeks (8.11.1) after the minor release they fix.

The practical consequence is that the curl project supports one line: the latest release. Security fixes go into the next release, not into older 8.x versions. If you need a fix on an old version, that work is done by whoever ships your curl, usually an operating system distribution or a device vendor.

Version numbers you can compare

The version numbering page explains the X.Y.Z scheme and one detail that helps automation. Every release defines LIBCURL_VERSION_NUM in curl/curlver.h as a hexadecimal number of the form 0xXXYYZZ, for example 0x081700 for 8.23.0 (0x17 is 23). That number always grows, so build scripts can compare versions numerically. Source tarballs are always named after the libcurl version, and the tool and library ship together with the same numbers.

Signed and reproducible releases

The verify page describes two controls. Each release tarball is signed with the release manager's published GPG key, and releases are reproducible: a scripts/verify-release script rebuilds a release from git and compares it with the downloaded tarball. The page also lists source controls such as no binary blobs in git, no force pushes on master and a copyright and licence statement on every file.

What does the curl security process look like?

The vulnerability disclosure policy on curl.se is the authoritative document. Here is how a report moves through it.

Reporting

Reporters file vulnerabilities on the bug bounty platform the project links from that page, where they reach a handful of trusted people. Issues believed to be below High severity may be filed directly on GitHub. The project does not accept vulnerability reports by email, because reports sent that way get lost and are hard to disclose. A private security mailing list exists for reaching the team, but the policy says it must not be used for reports.

Confirming and triage

Someone on the security team acknowledges each report so the reporter knows a human has seen it. The team then accepts or rejects it, and explains a rejection. Accepted Low and Medium issues are moved to the public GitHub issue tracker, ideally as a pull request, and are not handled privately any further. High and Critical issues stay private until a release with the fix can ship.

Severity: four levels, no CVSS

The team uses four levels: Low, Medium, High and Critical. The policy says it refrains from numerical scoring and does not set CVSS scores on the CVE records it publishes, because it considers CVSS a broken system that often does not reflect the real factors. It notes that other organisations do assign CVSS scores to curl CVEs and leaves it to readers to judge how well those assessors know the subject. When the team sets a level it considers attack vector and complexity, required privileges, build configuration, protocols, platform and impact.

Levelcurl's definition in short
LowTruly hard or unlikely to exploit or trigger: timing, rare platforms, rare options or protocols. Issues likely found by basic testing rarely rate higher than Low
MediumLess hard than Low; wider platforms or more common options; usually needs something else to happen to become serious
HighA serious problem with real world impact that can easily compromise confidentiality, integrity or availability, and is not hard to trigger
CriticalEasily exploitable by a remote unauthenticated attacker, leading to system compromise without user interaction, in a common configuration on a popular platform

So a curl "Medium" and a third party 9.8 for the same issue are two methods, not a contradiction. Read the advisory's conditions, then decide for your build.

Fixing, CVEs and the embargo

Low and Medium fixes go through normal public pull requests. High and Critical fixes are developed in a private branch that only the reporter and the security team can see. The team writes an advisory covering the problem, impact, affected versions, workarounds and credits, assigns a CWE, and requests a CVE ID. curl is a CVE Numbering Authority, so it issues its own CVE IDs.

No more than seven days before release the team informs the distros list at Openwall with the advisory draft and patch, noting that list does not accept embargoes longer than seven days and does not handle Windows only flaws. No more than 48 hours before release the private branch is merged and pushed, at which point the fix is public and the release follows immediately. Advisories go to the curl mailing lists and the oss-security list.

Full disclosure of every report

For transparency, the policy says all reports submitted to the project, valid or not, are disclosed once handled. That includes rejected reports, which is part of why the AI generated report problem described below became so visible.

What curl does not treat as a vulnerability

The policy lists issue types that do not qualify, including small memory leaks, never ending transfers, API misuse, attacks needing a local attacker already present, experimental or debug only features, URL parser differences with browsers, weak algorithms used only when explicitly requested, CRLF a user passes in, and unreleased code. Only releases are considered secure.

Under the current policy, Low or Medium reports that only affect releases older than three years are closed without action.

Major incidents

A separate major incident process covers events such as remote code execution with a public exploit, compromised curl infrastructure or a broken embargo. Only a security team member can declare one, naming an incident lead and a communication lead, and the policy says a declaration can be verified by asking two or more team members.

The CVE list and the vulnerability table

The curl CVEs page lists every published vulnerability with severity, affected versions and date; on 25 October 2026 it showed 239 entries. The vulnerability table shows the 25 most recent releases against each vulnerability, colour coded by severity, with a total per release. On the same date it showed 8.23.0 with no known vulnerabilities and 8.22.0 with 21. Each version links to a summary page (for example vuln-8.22.0.html), and the full list is available as JSON at vuln.json, which is the best source for automation.

Independent audits

The security audits page lists published third party audits of curl in 2016, 2022 (a threat model and code review published 21 December 2022), 2024 (HTTP/3 components, published 23 February 2024) and two in 2026. The page credits one 2026 effort, running from September 2025 to October 2026, with hundreds of bug fixes and 35 published vulnerabilities. That explains the high vulnerability counts against recent releases in the table: they reflect concentrated review, not a decline in code quality.

How did the curl bug bounty run, and why did it end?

The changelog lets you trace the bounty from start to finish:

DateReleaseChange recorded in the changelog
31 Oct 20187.62.0docs/BUG-BOUNTY added to explain the bounty program; the security process mentions a bounty platform
12 Dec 20187.63.0The security process notes that platform shut down again
22 May 20197.65.0"docs/BUG-BOUNTY: bug bounty time"
31 Mar 20217.76.0Mention of a cooperation removed from BUG-BOUNTY
22 May 20248.8.0Third party situation clarified
2 Apr 20258.13.0Vulnerabilities in debug code declared not eligible for a bounty
4 Jun 20258.14.1The medium bounty amount in 2025 mentioned
11 Mar 20268.19.0"we stop the bug-bounty end of Jan 2026"

Today the old bug bounty URL on curl.se redirects to the vulnerability disclosure policy, which opens with a plain statement: there is no bug bounty and the curl project never offers rewards for reported vulnerabilities. Reports are still welcome through the same channel; there is simply no payment.

The changelog records the decision, not the reasoning, and the curl.se policy pages do not state one. They do show the context: rules for AI assisted reports added in 2025 and a request that reporters write in their own voice.

How has the curl project handled AI generated bug reports?

curl's written rules on AI arrived in 8.14.0 (28 May 2025), when the changelog records "CONTRIBUTE: add project guidelines for AI use". The contribution page now has a section titled "On AI use in curl" with separate rules for security reports, pull requests and translations.

For security reports, the guide says you must disclose that an AI tool found the problem, must verify the finding yourself because AI tools "frequently generate inaccurate or fabricated results", and should write the report in your own words rather than paste generated text. Fake reports waste time the team would spend on real work, and users who submit made up reports are banned immediately.

The disclosure policy adds a general rule for all communication: explain issues briefly and clearly in your own voice, and do not paste long AI generated explanations.

For pull requests, AI assisted code is accepted if it meets the usual standards for style, documentation and tests, and the guide adds that if someone can tell a contribution was made with AI, there is more work to do. Translation tools are welcome, with a suggestion to mention them.

AI is not banned. The audits page lists a 2026 audit that used AI assistance and produced bug fixes and a CVE. The rule is about accountability: a human must verify, disclose and stand behind what they report.

Why is libcurl embedded almost everywhere?

curl's own history page gives the scale. In October 2018 it estimated curl and libcurl at 5 billion installations. In 2020 the estimate was 10 billion. By November 2025 the project had counted curl running on 110 operating systems and 28 CPU architectures. The official container image had been pulled more than six billion times by April 2024.

What drove that reach: an early library interface (2000), the MIT only licence (2002), bundling in operating systems (Mac OS X 10.1 in September 2001, Windows 10 from the 1803 release in March 2018, and Linux and BSD from the early years), language bindings starting with PHP 4.0.2, and pluggable TLS backends that made it portable. The project's companies page lists use in television sets, cars, motorcycle systems, printers and video games, among many other categories.

What that means for SBOMs

Wide reach means libcurl shows up beyond the operating system package (libcurl4 on Debian and Ubuntu, libcurl on Fedora and Alpine): statically linked inside Go, Rust or C programs with no package record, vendored in native language extensions, left in container base images for health checks, and inside appliances you do not build. An SBOM that lists only OS packages misses most of these. Search for both curl and libcurl, and use package URLs where your format records them.

What that means for backports

Because the curl project supports only its latest release, every long term support distribution backports security fixes into an older version. A server that reports curl 7.81.0 may contain fixes from years of later advisories. The upstream vulnerability table cannot tell you whether that build is affected; only your distribution's security tracker or changelog can. The reverse mistake is also common: a vendor product reports a recent version string but ships a libcurl built without the backports you assume.

Step by step: find every libcurl copy and plan upgrades

The steps below are read only. They find copies and versions; they do not change anything.

1. Check the command line tool and its library

curl --version
curl -V | head -1
curl-config --version 2>/dev/null
pkg-config --modversion libcurl 2>/dev/null

The first line of curl -V shows the curl, libcurl and TLS backend versions; the Protocols: and Features: lines show what was compiled in. If the tool and library versions differ, the tool is loading a different libcurl than it was built with.

2. See which shared library a binary loads

# Linux
ldd "$(command -v curl)" | grep -i curl
# macOS
otool -L "$(command -v curl)" | grep -i curl

Repeat for any binary you suspect links libcurl. Git's HTTPS transport is a common one:

ldd "$(git --exec-path)/git-remote-https" | grep -i curl

3. Query the package manager

# Debian and Ubuntu
dpkg -l 'libcurl*' 'curl' | grep '^ii'
apt-cache policy libcurl4 curl
# Fedora, RHEL and derivatives
rpm -qa 'curl*' 'libcurl*'
rpm -q --changelog libcurl | grep -i cve | head -20
# Alpine
apk info -v 2>/dev/null | grep -i curl
# macOS with Homebrew
brew list --versions curl 2>/dev/null

The rpm -q --changelog line is how you see which CVE fixes a distribution has backported, even when the version number looks old. Debian and Ubuntu publish the same information in their security trackers and in /usr/share/doc/libcurl4/changelog.Debian.gz.

4. Find processes that have libcurl loaded

sudo grep -l 'libcurl' /proc/[0-9]*/maps 2>/dev/null | cut -d/ -f3 | sort -u | \
  xargs -r -I{} ps -o pid=,comm= -p {}

This catches long running services that loaded an old libcurl before you upgraded the package. They keep using the old copy until restarted.

5. Look for static and bundled copies

libcurl builds embed a version string of the form libcurl/8.x.y. Searching binaries for it finds copies without a package record:

find /usr /opt /srv -type f -perm -u+x -size +100k 2>/dev/null | \
  while read -r f; do
    v=$(grep -a -o -m1 'libcurl/[0-9]\+\.[0-9]\+\.[0-9]\+' "$f" 2>/dev/null)
    [ -n "$v" ] && echo "$f $v"
  done

Check language runtimes too:

php -r 'echo curl_version()["version"], PHP_EOL;' 2>/dev/null
python3 -c 'import pycurl; print(pycurl.version)' 2>/dev/null

6. Check container images

docker run --rm --entrypoint sh your-image:tag -c 'curl -V 2>/dev/null | head -1; ls /usr/lib*/libcurl* /usr/lib/*/libcurl* 2>/dev/null'

Many images carry libcurl without a shell or curl binary, so an SBOM is the more reliable record. With the Safeguard CLI you can scan an image or a directory and get the components as JSON:

safeguard scan --image your-image:tag
safeguard scan --dir .

7. Search your SBOMs

For CycloneDX JSON:

jq -r '.components[]? | select(.name | test("curl"; "i")) | [.name, .version, (.purl // "")] | @tsv' sbom.cdx.json

For SPDX JSON:

jq -r '.packages[]? | select(.name | test("curl"; "i")) | [.name, .versionInfo] | @tsv' sbom.spdx.json

If you keep SBOMs in Safeguard, the platform shows which projects contain a given component and version, so you can ask the question once for the whole estate. You can also scan an existing SBOM file with safeguard scan --sbom sbom.cdx.json.

8. Read the advisories that apply to each version

For every distinct upstream version you found, open its summary page on curl.se, for example https://curl.se/docs/vuln-8.22.0.html. For automation, fetch the JSON list:

curl -s -m 20 https://curl.se/docs/vuln.json -o curl-vulns.json
jq -r '.[] | [.id, (.aliases // [] | join(",")), .summary] | @tsv' curl-vulns.json | head

Many curl advisories apply only to a specific protocol, backend or option, so compare them with the Protocols: and Features: lines of your build and record why you ruled any out.

For distribution packages, use the distribution's own tracker, not the upstream table, because of backports.

9. Map each copy to a plan

What you foundWhat to do
Distribution package on a supported releaseApply distribution updates; restart services that loaded libcurl
Distribution package on an end of life releasePlan the OS upgrade; the upstream fix will not arrive
Self built curl or libcurlMove to the latest release; you get fixes only by upgrading
Static copy inside a third party binaryAsk the vendor for their libcurl version and backport status
Static copy inside your own binaryRebuild against the current libcurl and redeploy
Container imageRebuild on an updated base image and redeploy
Built with a removed backend (NSS, BearSSL, Secure Transport, gskit, hyper, msh3)Switch backend before upgrading; the old one will not build
Scripts using -k or --insecureFix the trust problem and remove the flag

10. Test before you roll out

Check the deprecation page for anything you depend on, run your integration tests with the new libcurl, and compare the Features: line before and after. Builds that relied on NTLM or SMB need explicit build options since 8.20.0, and SMB is gone in 8.23.0.

Common mistakes

  • Updating the curl binary but not the statically linked libcurl. Upgrading the curl package fixes the tool and the shared library. It does nothing for programs that carry their own static libcurl, and it does nothing for processes that loaded the old library until they restart.
  • Using -k or --insecure in scripts. Since 7.10 in 2002, curl verifies certificates by default. -k switches that off. The known risks page warns that unverified transfers can be intercepted and that servers can be spoofed. Fix the CA bundle or use --cacert instead.
  • Ignoring deprecated backends. A build pinned to NSS, BearSSL, Secure Transport, gskit, hyper or msh3 cannot move to a current release without a backend change, so it quietly stops getting fixes. Watch the deprecation page.
  • Assuming distribution version strings show backported fixes. A distribution's 7.81.0 is not upstream 7.81.0. Use the distribution tracker or package changelog, not the upstream vulnerability table, to judge exposure.
  • Treating release candidates or git master as production code. curl's policy says only releases are considered secure.
  • Searching SBOMs for "curl" only. Search for libcurl too, and check whether your SBOM tool records statically linked libraries.

FAQ

When was curl first released?

The first release under the name curl was version 4.0 on 20 March 1998. Its predecessor, HttpGet, was first released on 11 November 1996 by Rafael Sagula, and Daniel Stenberg's first release of it was HttpGet 0.2 on 17 December 1996.

Who maintains curl?

Daniel Stenberg leads the project in a BDFL style, with a group of maintainers who have push access and a small security team. There is no legal entity behind it, according to the governance page.

What is the latest version of curl?

As of 25 October 2026, curl 8.23.0, released on 14 October 2026. The next release is planned for 9 December 2026.

How often does curl release?

Every 8 weeks on Wednesdays, with patch releases in between when a regression or serious problem needs one.

Does curl still have a bug bounty?

No. The changelog records the decision to stop the bug bounty at the end of January 2026, and the disclosure policy says there is no bug bounty and no rewards.

Does curl support HTTP/3?

Yes. HTTP/3 using ngtcp2 has been non experimental since December 2023. HTTP/3 with quiche is still experimental, and the msh3 and OpenSSL-QUIC backends were removed in 8.16.0 and 8.19.0.

Which TLS libraries can curl use?

As of October 2026, the comparison page lists OpenSSL (and forks such as LibreSSL, BoringSSL, AWS-LC and quictls), GnuTLS, wolfSSL, mbedTLS, Schannel and rustls, with rustls still marked experimental. Removed backends include NSS, gskit, BearSSL, Secure Transport, axTLS, PolarSSL and MesaLink.

Is my distribution's old curl version vulnerable?

Not necessarily. Distributions backport fixes, so the version string alone does not tell you. Check the distribution's security tracker or package changelog.

Why supply chain hygiene still matters here

curl is the clearest example of a dependency that sits under everything and gets fixed only in its latest release, so whatever you ship carries whichever libcurl was there when it was built. Rebuilding images, refreshing pinned dependencies and confirming fixed versions is the part of curl hygiene you control, and the steps below are how Safeguard helps with that part.

Fix it without waiting for upstream

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation categories include dependencies, licenses, security posture and findings, and each one is set separately. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.

3. Gold Registry: start from components that are already fixed

Gold Registry provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. Ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingSafeguard policies and gates in CI
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

Safeguard does not patch curl on hosts you manage outside your builds, and it does not replace your distribution's security updates. Where it helps is the part this post spends most time on: finding which repositories, images and SBOMs carry libcurl at which version, and acting on that list.

The first demo sets up the Safeguard runner on your own machine, approves it with a device code, and runs a scan from the terminal. For curl, that is the step where you point the scan at a repository or an image and get back every component, including libcurl, as JSON you can search.

Click through it at your own pace, or open it full screen.

The second demo is a real Safeguard CLI session. You ask it to fix a vulnerable dependency, it reads the finding and the advisory, asks before any command that changes something, edits the manifest, runs the install and tests with your approval, and prints a summary without pushing. The same flow applies when a language binding or base image pins an old libcurl.

Click through it at your own pace, or open it full screen.

The third demo connects Claude to the Safeguard MCP server with OAuth and lets you choose which tools Claude can use. That makes it possible to ask, in plain language, which of your projects contain libcurl and which versions they carry.

Click through it at your own pace, or open it full screen.

To try it on your own estate, download Safeguard and follow the CLI docs.

Quick check

You upgraded the curl package on a server last week. Is every program on that server now using the fixed libcurl?

Not necessarily. Processes that loaded libcurl before the upgrade keep the old copy until they restart, and programs that link libcurl statically carry their own copy that the package upgrade never touches. Check loaded libraries in /proc and search binaries for the libcurl version string.

Your distribution reports curl 7.81.0, and the upstream vulnerability table lists dozens of CVEs against that version. Are you exposed to all of them?

You cannot tell from the upstream table. Distributions backport security fixes into older versions, so check the distribution's security tracker or the package changelog to see which fixes are already included.

Related reading

Sources

Last reviewed: 25 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.