Category Archives: cURL and libcurl

curl and/or libcurl related

A curl mountain movie

One of my favorite visuals for known vulnerabilities in curl is the mountain. It shows how many currently known vulnerabilities were present in the code through-out curl’s history.

In the end of June 2026 it looks like this:

Over time we get more vulnerabilities reported. Since every flaw has a version range during which the problem existed and with more issues that have overlapping version ranges, the mountain grows. It changes shape every time we do a release or we publish a new vulnerability.

At this moment in time, curl version 7.34.0 is the release that contains the most number of known vulnerabilities: 101. The worst one ever if you will. Out of a total of 206.

The mountain uses different colors for different severity levels of the published vulnerabilities, as the legend in the top-left of the image explains.

To illustrate the ever-changing nature of the shape and size, I wrote a script that renders the mountain the way it looked at specific dates in the past up until today. More specifically, the script renders one image for every month since curl started (March 1998). I then turned these 340 individual images into a little movie that shows how it grew into today’s shape. At four months/second.

The data for this come from vuln.pm and the curl git repository. The graph rendering is based on the dashboard scripts. All images put into a movie with ffmpeg of course.

The 2016 drop

Several people have asked what happened in 2016 that caused the notable drop. A slope if you will.

If we zoom in on that, we can spot that curl 7.51.0 has eleven fewer vulnerabilities than the version before that. This release was the first one after the 2016 Cure53 code audit, but other than that there is no clear distinct process or obvious code changes that explain this trend shift.

Lots of other graphs show just the ordinary pace and growth in various project areas. It was still fairly early days CI-wise but had been running at least a few CI jobs per commit for a few years already by then.

curl was adopted into the OSS-Fuzz project in July 2017, which since then makes us find some issues better, but the drop looks like it happened before then.

We had already been analyzing the code regularly on Coverity since a few years.

Better tooling? New compiler options? We simply don’t know.

Future

As we keep announcing more vulnerabilities going forward, things will continue to change. Maybe I will come back and make another movie in five years?

Trailing dots are the worst

Trailing dots after hostnames in URLs remain my worst enemies. I wrote about several problems with them in the past that involved those nasty things. They are still painful. When we shipped curl 8.21.0 on June 24 2026 we fixed at least three brand new problems that involved trailing dots. C’mon, follow me down the trailing dot rabbit hole, episode two. I can just feel that there will be a third episode as well in a future…

IPv4 numerical address

Let’s for a second imagine that you create a URL that uses a numerical IPv4 address. Not entirely uncommon. For example lots of people use 127.0.0.1 in local tests etc. Used everywhere since the dawn of time.

Now imagine that you add a trailing dot to this hostname, like “192.168.0.1.”. What does the trailing dot even mean here?

This particular trailing dot caused a problem in curl. To figure out if curl should allow wildcard certificates when connecting to a TLS server, it needs to know if the given hostname is a numerical IP or a hostname. The check uses inet_pton() on the provided hostname extracted from the URL – which incidentally returns false for an IPv4 address that ends with dot! So if it isn’t a numerical address it is a hostname and then we allow wildcards… Argh.

I decided to solve this particular problem like this: if the address is a valid IPv4 address and there is only a single dot afterwards, that dot is “swallowed” as part of the regular IPv4 normalization process that curl always does for IPv4 addresses when parsing URLs. This way, a numerical IPv4 address with a trailing dot will never be passed on to curl internals anymore. And the meaning of the trailing dot for this use case is clear: it is a mistake so we get rid of it. (This also seems to be what browsers do.) Shipping in curl 8.21.0.

This choice has already been reported problematic by at least one user who expected a transfer for a URL like this to return error… I suppose this means that the jury is still out on what the best approach for this trailing dot is.

Double trailing dots HSTS

What could be more fun than trailing dots if not two trailing dots!

Two trailing dots is not possible to use as a hostname when resolving hostnames using DNS. It is an illegal name and causes an error. But as curl provides other ways to populate the DNS cache with a provided name, and you can provide names in /etc/hosts etc you can make curl work with URLs where the hostname has two trailing dots. Or rather, you could up until recently until I made sure it is properly banned always because of the trouble they cause internally.

A double-dot is correctly treated as a host with a trailing dot, but it turns out that in for example the HSTS logic that became problematic as removing the trailing dot for some functions would still have a trailing dot there when there were two of them to begin with… and it would get confused and act up.

No more double trailing dots. One is annoying enough. Shipping in curl 8.21.0.

Cookie domain

HTTP cookies are basically name/value pairs set by the server and held by the client to get sent back to the server again in later communications. The server can specify for which domain a cookie should apply to, so that it can be used across multiple domains. (Yes, it is a little crazy,)

To prevent the server from being able to set the cookie on a too wide domain cookie clients check if the specified domain is Public Suffic Domain (PSL) or not. A server is not allowed to set cookies for PSL domains, as that allows it to create “super cookies” that work across domains in ways that are not allowed. Cookies attempted to get set for such a name should be rejected.

In libcurl we check domains against the PSL using the libpsl library.

Turns out this too could be tricked by trailing dots. If you communicate with the URL “example.co.uk.” (with a trailing dot) and it sets a cookie for for “co.uk.” (with a trailing dot), the internal check would ask libpsl about the PSL status and… it did not work with trailing dots. The exact same process without trailing dots correctly says it is a PSL and the cookie is refused. But with the trailing dots present it was fooled and curl would allow the cookie to get stored and later sent back to such a host…

This particular issue ended up considered a vulnerability known as CVE-2026-8924. Fix shipped in curl 8.21.0.

We should consider these things

Yes, you can of course quite correctly argue that none of these things are actually new or sudden changes. Trailing dots are there, they have always been there and people will continue to use them in the future. I’m not blaming anyone else. I’m just expressing my frustration.

Trailing dots are the worst.

a CVE dispute

A few years years ago the curl project signed up and became a CNA. This means that we are masters of and can allocate our own CVE identifiers. For any security problems within our territory, it is we who decides if the issue should get a CVE or not. No more bogus CVEs.

57 CVEs

During these years we have published fifty-seven separate security vulnerabilities with their associated CVE identifiers. Getting a CVE for an issue is easy and really quickly done when you are a CNA. No hassle, no friction and as we are a small and lean security team it just works as smoothly as you could ask. Just an API call and we have new number.

Being a CNA is low maintenance, as there really is nothing extra we need to do. We already had an established and proven process for receiving, managing and assessing vulnerability reports before we became a CNA since we are a responsible and well-run Open Source project. Becoming a CNA just made the process easier as we now don’t need to involve any outsider at all.

Assess

For every report we work hard to first assess and decide if the issue is actually a vulnerability or a security problem at all.

If we deem that there is a security problem in there, we then grade it into LOW, MEDIUM, HIGH or CRITICAL. Since we don’t know how users use curl or libcurl we cannot take that into account but rather observe and set a severity of the problem from a pure curl point of view.

It’s a rough indication how we see the problem but of course every user that actually are affected by the problem might rate it differently.

Lower than LOW

For a rare few issues we can imagine that there could be a minuscule risk but because of the set of extreme requirements and convoluted steps to get there, we deem the risk so small that in practice no user is likely to ever reach it. Internally we tend to call that an issue with a severity level lower than LOW. Issues we believe we serve humanity better by not issuing a CVE for. To avoid the security dance when it seems unnecessary.

The cost of a CVE

libcurl is installed in somewhere around thirty billion instances on the globe. If we imagine that at least a sizeable portion of those installs are managed by people who want to make sure they use a secure version, it means that every CVE we publish trigger activities in many security teams all over the world, leading to a significant number of patches and subsequent software updates.

Every CVE thus has this huge cost tied to it. A cost that does not land on us and we don’t really see or feel it, but a cost on the ecosystem I believe we should not ignore. We should act responsibly. Never ignore real problems of course, but also to make sure we don’t ring the alarm for theoretical problems that will not trigger any vulnerability.

The dispute

Our first ever CVE dispute since we became a CNA reached us on February 10th, 2026 for a report submitted to us two months earlier. The reporter thinks we should have assigned their reported problem a CVE but we think not. Now they want to force the issue to get a CVE anyway, by escalating the situation to MITRE.

Yes, it makes you wonder why it is that important to have this as a CVE, but I will avoid speculations for now.

I replied to MITRE explaining that we considered and debated the issue and we remain happy with our previous decision. I linked them the original report and discussion to show them.

Hostname with a leading dot

The issue is quite technical (of course) but is based on a bug in curl’s function that checks if the used hostname matches a wildcard provided in a certificate.

First: the user must use a hostname in a URL with a leading dot, like https://.example.com/

This name is not possible to use with DNS (it is an illegal name there), but you can provide an IP address for it in your /etc/hosts file or similar, but still this condition is already making this issue really niche.

Why would a user ever do this? Well, there could be a redirect to such a host name from a malicious server if the application allows redirects but getting the address for the host is still a challenge and mostly requires a local attacker present add that.

Then: if curl can find an address for the illegal DNS hostname, the site curl connects to, also needs to have a wildcard certificate for the name *.example.com where the tail of the wildcard needs to match the name in the URL.

If curl was built to use an OpenSSL flavor or Schannel for TLS (remember that curl supports many different TLS backends), it then calls the Curl_cert_hostcheck() function to check if the wildcard covers the used hostname.

This function had a bug. The above mention combination then erroneously would return TRUE. A match. When in reality it is not a match according to the spec.

We fixed this problem on December 8, 2025, and we added unit tests for exactly this scenario to make sure that the problem doesn’t come back. For all security issues at several below HIGH, we fix them asap so that was just our normal procedure. We then continued to discuss if this was worthy of a CVE or not.

Lower than LOW

It should be extremely rare that anyone uses a dot prefixed name, unless you are in an internal and controlled environment where you use something else than DNS for resolving.

It is not possible to trick an application to use a dot prefixed arbitrary name as it will fail to resolve.

The explicitly set, weirdly dot prefixed name, then needs to connect to a host that has a wildcard set for that same name and an attacker manage to run this impostor host and can now serve the application malicious data because curl did not properly reject the connection because of the wildcard mismatch.

A series of highly unlikely conditions that all need to be fulfilled for this to become a vulnerability. A lower than LOW situation. Too unlikely; no CVE.

Again in May

On May 28, we were again contacted by MITRE in the same case, asking again for our rationale for not giving this issue a CVE. We responded with virtually the same wording as before and linking again to the same original Hackerone issue and discussion thread. It’s all public information really.

Again in June

On June 15, we were again contacted by MITRE asking for the reasoning behind our decision to not give a CVE for this issue.

We replied with similar wording again. Linking to the same issue, again.

This seems like a great system.

Verdict

On June 24 we finally got the verdict. It is not considered a security vulnerability.

Hello Yuhao,

Thank you for your participation in the CVE dispute process regarding the reported issue affecting curl through 8.17.0.

The MITRE TL-Root has completed its review of the information provided by all parties involved,
including the materials submitted by you and the response from the responsible CNA. Based on this
review, the MITRE TL-Root has determined that a CVE ID will not be assigned for the reported issue.

CNA Determination (Summary):

"This is a bug, now fixed in the master branch. It is not considered a security vulnerability because of how it requires a local attacker with privileges present to make it so."

After evaluating the available evidence and the CNA’s assessment, the MITRE TL-Root agrees with this determination and considers the matter resolved. As the adjudicating authority in this dispute process, the decision of the MITRE TL-Root represents the final determination for this case.

We appreciate your engagement with the CVE Program and your efforts to responsibly report and coordinate security issues.

Respectfully,

MITRE TL-Root

curl 8.21.0

Release presentation

Numbers

the 275th release
6 changes
56 days (total: 10,817)
276 bugfixes (total: 14,187)
531 commits (total: 39,077)
0 new public libcurl function (total: 100)
0 new curl_easy_setopt() option (total: 308)
1 new curl command line option (total: 274)
102 contributors, 69 new (total: 3,731)
45 authors, 26 new (total: 1,489)
18 security fixes (total: 206)

Security

As mentioned before, the security report volume has been intense lately. We publish eighteen new curl vulnerabilities this time. A new project record for a single release and for the total number of vulnerabilities published within the same calendar year.

As always, we have document each vulnerability in detail and I encourage you to read up on the details.

Severity Medium

Severity Low

Changes

The huge focus on vulnerability reports during this release cycle made us merge fewer new features than we wanted, but here are the ones we still managed to get to:

  • curl: named globs
  • curl: named globs in output file name for uploads
  • HTTP/3 proxy CONNECT and MASQUE CONNECT-UDP support
  • removed HTTP/2 stream dependency tracking
  • removed support for CURLAUTH_DIGEST_IE
  • added support for SHA256 host public keys with libssh

Bugfixes

We again manage to land more than 250 separate bugfixes, and they are all detailed in the changelog.

Pending removals

Planned upcoming removals include:

  • local crypto implementations
  • NTLM
  • SMB
  • TLS-SRP support

If you are concerned about any of these, speak up on the curl-library list ASAP.

Next release

Unless we messed up this one and need to do a patch release, the pending next release is scheduled to happen on September 2. This release cycle is extended by two weeks due to the summer of bliss.

QUERY with curl

RFC 10008 is brand new a specification detailing the new HTTP method called QUERY:

This specification defines the QUERY method for HTTP. A QUERY requests that the request target process the enclosed content in a safe and idempotent manner and then respond with the result of that processing. This is similar to POST requests but can be automatically repeated or restarted without concern for partial state changes

A GET with body

For all practical purposes you can think of QUERY as a way to send a GET with a body. It looks exactly like POST, but done with another verb.

Contrary to POST, QUERY requests are idempotent – they can be retried or repeated when needed, for instance after a connection failure.

curl it

You can use curl to do HTTP requests with QUERY just fine. curl offers the --request option (also known as -X in the short form) that you can use like this:

curl -d "data to send" -X QUERY https://example.com/

But redirects!

There is one little caveat to remember with this curl option that changes the method. When also asking curl to follow any possible redirects, it is important that you use a new enough curl version because you want the --follow option. Not the old --location/-L one.

Why? Because the old option changes the HTTP method on all subsequent requests independently of what the server responds, which in many cases is not what you want.

The newer --follow option instead acts according to what the HTTP response code suggests in should do. Stick to the same method again, or maybe switch to GET in the following request.

Why?

Why or when would you use this? First of course you only want to use this if the server supports it, but the spec offers some reasons why this might be a good choice:

  • avoid or circumvent URL size limits. Somewhere around 8000 bytes they start to no longer work reliably because servers and intermediaries set limits.
  • expressing certain kinds of data in the URL is inefficient because encoding overhead
  • URLs are more likely to be logged than request content

curl summer of bliss

The curl project will not accept or otherwise handle any vulnerability reports during the month of July 2026. We call it the curl summer of bliss.

curl’s submission form on Hackerone will be paused starting July 1, 2026.

Summer of bliss starts: July 1, 2026. 00:00 CEST

Submissions resume: August 3 2026. 09:00 CEST

The security email address will also be a dead end, as we will not process or otherwise care about security or vulnerability reports sent to us that way either.

Whatever issue you find that you feel a need to report to the curl project during this month has to wait. curl’s Hackerone form opens for submissions again on Monday August 3.

We do not accept vulnerability reports over email in general, and this fact remains during and after our vacation.

Vacation for real

The curl maintainers will use this time of less pressure to take in some extra air and to enjoy the summer. Maybe stroll outside a bit more. Breath. Some of us may spend some of this time to see other places.

We may get some extra time to spend on fixing bugs or working on new code. Fun stuff!

Side-effects

As a direct side-effect of this summer of bliss, to allow us some more time to handle the issues that might have piled up for us in early August, we also push the release date of 8.22.0 two weeks into the future. Now scheduled to happen on September 2, 2026.

Vulnerability rate

As previously mentioned, we have been under a huge pressure for the last four months or so. Now we need some rest. We do not expect this deluge to be over.

GitHub

curl’s issue and pull-request trackers on GitHub remain open and active like normal.

You too?

If you and your Open Source projects also want to participate in the summer of bliss 2026: just do it and let us know! I would of course encourage you to do so. To take care of yourself as a top priority.

The bad guys won’t rest

Probably not. But we will.

But what if there is an emergency

Then we get to read about it in August. Or you get a support contract and we get to read about it earlier.

Contracts excluded

Everyone with a paid support contracts will of course still get full and appropriate service even during this period.

Credits

The ice cream image was made by fotografierende from Pixabay

Discussed

On hacker news.

A human in control

There seems to be a fair amount of people in either extremes in the current AI landscape. At one side we see the “vibe coders” who use agents and allow them to merge code without any person even looking at the source, while on the other side of the field there are people who are against everything and anything even remotely associated with AI.

My personal stance is somewhere in between, as I suppose shouldn’t be too surprising to readers of this blog.

A work of love and pride

The core team behind curl, and that is more people than just me, consists of individuals to whom code quality and source code excellence is important. We do software development because it is a craft we love and we are proud of what we have accomplished this far. We do not hand over our responsibilities to any machines. We stand for every bit of code we merge – as humans.

AIs do mistakes

Blindly accepting code written by AI means that you merge a certain amount of errors, but this is certainly true for human written code as well, so this is not in itself special. Some data suggests that AI generated code might even contain more mistakes than the human versions.

We invented test cases and code review a long time ago as a means to help us combat and reduce mistakes to get merged. The particular way code was written does not take away the benefits from code review and getting additional checks and eyes on pending changes. A good code review helps spotting mistakes, omissions or slip-ups. It also helps reinforce the architecture and established design choices. This is true however the code was created.

This far, code reviews done by automatic AI bots and the likes have not yet managed to replace the humans. They are simply not good enough.

Human reviews are much better. They catch other things and they help make sure proposed changes stay on track.

Not to mention how I want to know how curl works, even if I don’t keep 100% intimate knowledge of every single angle and corner, I know most of it. I think it helps me make better decisions, debug better, help users better and keep the architecture sound.

Getting the initial code written is not the big deal. For curl, maintaining and polishing the landed code through decades is the real task.

Everything we merge in curl is determined fine and fitting by humans.

Humans do mistakes

In all living software projects we get bugs reported and we fix them. We do new releases and continue to iterate. We have done this since software was invented and we still do, as humans are quite fallible and easily make mistakes.

We try to reduce the error density and frequency by adding tests and by adding more human eyes on the code before we green-light it. It helps, but is not perfect.

To help us do better code we invent, introduce and enforce a wide variety of different tools. With tools that look at code and identify problems in the early stages, they help avoid landing bad code in the first place. They make us do better code. They reduce the bug frequency.

Some of the best tools for detecting coding mistakes today use AI. These tools might work on existing source code in a git repository or they might look at proposed changes in pull-requests.

Above I mentioned that human code reviews are better; but the opposite is also true. In a somewhat complicated change request, it is now common that after the humans can’t spot any more problems, the AI PR review bots can still find an issue or two to remark on. Sure, sometimes they are wrong and then the comment is easily dismissed, but more often than not the findings they point out are actually something worth addressing before merge.

curl is developed and driven by humans, assisted by tools.

Communication is for humans

Open Source is about sharing code and is a development model where we do things in the open. The communication part of this model is key. Share your ideas, your visions, your problems or maybe just your ideas for what to do this afternoon.

Express what you want or what the problem is, and the team can respond and we can work together on fixing and improving whatever needs to be done.

Effective communication, a condition for good Open Source, implies human-to-human interaction. Inserting a large AI generated tone-deaf large wall-of-text into such a flow can still work, but only in the same way humans can learn to work with difficult individuals as well. It is not ideal and it is not a smooth way of working. It introduces sand in the machine. Don’t do that. It is rude.

Effective Open Source work means we communicate as humans, even if parts of the work and the code is made with the help of AI.

The combination

Humans and machines excel at different things. We can complement each other in software development.

Everyone is free to act to their own will, but in the curl project we don’t hand over responsibility to machines. We stand for our product. We make it as good as we possibly can; using all the tools that are available to us. I claim that in order to do this, humans need to remain in control.

curl up 2026 summary

Getting curl developers and related enthusiasts into a single room to hang out in the real world for a whole weekend once a year is awesome.

We find inspiration, we share experiences, we learn from each other and we dream and plan of future endeavors and things to work on. Seeing faces, hearing voices and watching body language help us communicate better virtually and on video calls during the rest of the year.

We have gathered curl people like this annually since 2017, even if some years during Covid were “different”. To me, this is one of the best events of the year. I get to hang out and talk curl with good friends a whole weekend!

The 2026 edition was held in Prague in late May and kept the general style of past events. About 25 people got into the room. We had five curl maintainers present and quite a lot of local curious minds.

The curl up format is easy, casual and friendly. We do topical presentations, followed up with Q&A and discussions around the topics brought up – of course usually with reflections about curl’s role, both past and future. We live-stream and record the presentations to allow our friends who could not attend to keep up both in real-time but also after the fact.

Unfortunately the tech is not always on our side so the quality sometimes is a little lacking. This year I brought an HDMI-splitter and an HDMI-to-USB device to allow us to get better recordings, but they were not working as smoothly as intended so we had to use inferior backup solutions for most of the meetup.

Recorded talks

This presentation above was the “keynote”, the introduction talk to the event. We then also recorded another nine session that are all available in the curl up 2026 playlist on YouTube.

Photos

To give you all a little glimpse of what curl up is about, here’s a gallery showing some of the speakers and some scenery.

All photos taken by and donated to us by an anonymous curl fan present in the room.

The pressure

I’m doing Open Source primarily because I love it. The social aspects, the for-the-good angle and for the challenge of engineering this to work for everyone. I also do it because it is my full-time job and getting food on the table and provide for my family is not unimportant. It may come as a shock, but I am not in this game for the money or the extravagant life style.

I have been working full-time on curl since 2019. For me, this typically means doing 50 hour work weeks, as I spend all days on it and then I top them off with a few more hours every late night – all days of the week, I spend all this time on curl because it is a work of love and it is both my job and my spare time hobby and no one counts my hours anyway. (And no, I do not recommend anyone else to do the same. I’m not suggesting this for others.)

I consider my primary work-related mission in life to be to make curl the best transfer library and tool possible and make it qualify as a top project in Open Source, quality, performance and not the least, security. I believe we generally meet these lofty goals.

I founded the curl project, I am still a lead developer in the project almost thirty years later. While I always clearly state that curl is not a one-man shop and that curl would absolutely not be what it is without my awesome curl team mates, a large part of the world still thinks of curl as my project and sometimes more or less equals curl with my person.

I cannot help to take curl issues personally. When someone critiques curl, it is by extension a complaint on decisions and choices I stand by and behind – and many cases I made the calls. curl is personal to me. curl has formed my life forever.

I have two kids. They were both born many years after I started working on curl and they are both adults and independent individuals now. I love them dearly. Life passes by but curl remains. We’ve had slow times and busy times. The decades pass.

Later this year the curl project celebrates thirty years. We typically repeat that the number of curl installations in the world is perhaps thirty billion.

Things changed

Over the last years I have done numerous blog posts on the state of security reports submitted to curl. They have gradually switched over from complaints on stupid LLMs, to stupid AI slop reports, closing the bug bounty over to the current high quality chaos which for us started maybe at some point in March 2026.

We have seen many spectacular security failures through the years, in Internet products, in software infrastructure and in Open Source. Every time we read about those events, we get reminded about how curl is everywhere and how we really really really do not want anything such to happen to us or our users. And we take another lap around the project, tighten every bolt a little more, add a few more checks, tests and guidelines to ideally make the curl ship ever so slightly less likely to ever leak or sink.

Scrutinized

Recently, after I pointed out that Mythos only found a single low severity problem in curl in its first scan, countless people have repeated the claim that curl is one of the most scrutinized, most reviewed, most fuzzed and most verified source codes you can imagine. Perhaps that’s true, but I just want to mention this: that’s not by mistake. That’s not an accident or a happy circumstance. That’s the result of relentless work and attention to details through decades. Software engineering done right. Iterative improvements over time that simply never ends is an effective method.

This does not however mean that we don’t have bugs or that we don’t have security problems left, because we do. We have hundreds of thousands of lines of source code that is doing highly parallel networking for many protocols on all imaginable operating systems and CPU architectures – in C. So we fix the problems, patch them up and ship new releases. Over and over.

Thirty billion installations world-wide means that everyone reading this blog post has curl installed multiple times in stuff they own. In phones, tablets, cars, TVs, printers, game consoles, kitchen equipment and more. Not to mention all the online digital services we use and those devices communicate with. I cannot stress the importance of curl security and I would guess that most of you agree with me.

I am jealous of those projects that shipped a horrible bug at some point in the past that made the world burn for a while. They got attention and some of them then got funding and financial muscles to get them staff and hire multiple full time engineers. I sometimes think we would be better off if we also had one of those.

Never-before experienced

A thirty years old project could make you think you’ve seen most things already, but we have not been in this situation before.

The rate of incoming security reports is 4-5 times higher than it was in 2024 and double the speed of 2025 – meaning that on average we now get more than one report per day. The quality is way higher than ever before. The reports are typically very detailed and long.

In order to manage this incoming flood of submissions, we need to make sure to handle them as soon as possible as we know there are more coming. If we don’t take care of them roughly at the same speed they arrive, the backlog just grows and having that list of potential security problems in a list that you don’t have control over takes a mental toll.

I spend almost all my days right now working through the list of reported security issues that we have on Hackerone. Verify the claim, assess the importance, write a patch, figure out when the bug was introduced, understand the vulnerability, write a detailed advisory explaining the problem to the world and communicate all this with the security researcher and the rest of the curl security team.

A health concern

For the first time in my life, my wife voiced concerns about my work hours and my imbalanced work/life situation. I work more than I’ve done before, but the flood keeps coming. People in my surrounding, I guess reading between the lines, have asked me how I and we cope with this deluge and want to make sure we don’t burn in the process. I am concerned for my team mates.

I might soon have to reduce my work hours to allow myself more breathing time.

This is a never-before seen or experienced pressure on the curl project and its security team members. An avalanche of high priority work that trumps all other things in the project that is primarily mental because we certainly could ignore them all if we wanted, but we feel a responsibility, we have a conscience and we are proud about our work. We feel obliged to fix security problems in the software we have helped shipped to every device on the globe. This is personal to us.

With about half the release cycle left until the pending release ships, we already have twelve confirmed vulnerabilities meaning twelve pending CVE announcements. That’s a new project record and it also means we will reach thirty published CVEs in 2026 even before half the calendar year has passed. The projected total amount of curl CVEs published through the whole year is therefore at least double this number!

Assistance

What help would we like? Short term it is a little late. We already have work up to our ears.

I wish more companies that use and depend upon curl or libcurl in commercial software and services would chime in their part to fund us. We could then pay more developers to distribute the work load across. That would be great. Feel free to contact me to discuss how you can contribute to this. Get your employer to pay for a support contract!

Fortunately we have customers who already do this, so some of us can work on curl full time.

I am a pragmatic (and a bit of a cynic) and I have danced this dance for a long time already. I have no illusions that anything significant is going to change in this area even if we are in an unparalleled situation and in a tighter spot than ever before. I totally expect us to ride out this storm by ourselves. Like we are used to. We will survive. We will endure. It might just be a bit of a shaky period in the project and in the world at large as we try to maneuver our way through this. There’s a tsunami coming over us and all we can do is swim, there are no life boats for us.

The curl project is not owned by a company. We are not part of any umbrella organization. This makes us a little under-powered at times, but it also gives us maximum freedom and flexibility. We act solely in the interest of making curl as good as possible for the world and curl users.

The good part

Fixing bugs and problems is good. Every reported problem implies a fixed issue. curl becomes a better product.

What is also a good trend: almost no one finds terrible vulnerabilities. All vulnerabilities found the last few years in curl have all been deemed severity LOW or MEDIUM. I’m not saying there won’t be any more HIGH ever, but at least they are rare. The most recent severity high curl CVE was published in October 2023.

Pressure

Right now we are under a little pressure. Forgive us if we are a little slow to respond sometimes.

Credits

Image by Brian Merrill from Pixabay

named globs with curl

One of the established power features of the curl command line tool is its support for “globbing”. It is a built-in way to specify ranges and sets in different ways and have curl iterate over them to simplify repeated transfers.

For example, you can easily download three images from the same host without having to repeat the almost same URL three times:

curl -O "https://img.example/{flower,house,garden}.jpg"

Or if you have them in a numbered range, you can get a thousand images in a single tiny command line:

curl -O "https://img.example/photo[1-1000].jpg"

And they can be combined in crazy ways:

curl -O "https://example.{org,com}/{apples,mugs,coins}/img[1-1000].jpg"

curl allows globs used in a single URL to create up to 263 permutations – which, if you can do one million transfers per second, would take 292 thousand years to complete.

(As an added bonus you can of course also add -Z to the command line to make curl transfer all those images in parallel rather than serially.)

Saving them

To help users save files when using globbing, curl provides a way to reference the globbed components using #[number] when setting the target filename. The number then references the specific glob, where the first is 1, the second 2 etc.

Saving the one thousand images using different filenames locally than they use remotely:

curl "https://img.example/photo[1-1000].jpg" -o "local-#1.jpeg"

This allows a compact command line to also offer flexibility.

News coming in 8.21.0

All functionality mentioned above has existed in curl for years; decades even. It just so happened that one day when working with curl I fell over a use case that I could not solve with the existing command line functionality.

I wanted to do a globbed upload to a HTTP server and then save all the separate responses into their own dedicated files, preferably with names based on the glob.

I will admit that I at first had a hard time to accept the fact that we actually could not do this already, but that was then rather quickly instead turned into: how should I add support for this in the smoothest and most convenient way? Using what syntax?

The road to fixing it for uploads took a little detour.

Name instead of index

Starting in 8.21.0, curl can assign a name to each glob and then reference that glob by name instead of using just a glob index number. This allows command lines to get ever so slightly more readable I think.

The image range example from above, but instead using named globs:

curl "https://img.example/photo[<number>1-1000].jpg" -o "local-#<number>.jpeg"

Or a version with three separate globs where they all are used in the output file name:

curl "https://example.{<tld>org,com}/{<object>apples,mugs,coins}/img[<index>1-1000].jpg" -o "file-#<index>-#<tld>-#<object>"

Slick, right?

Uploads

Back to the globbed upload challenge:

curl -T "{one,two,three}.jpg" https://ul.example/

… but with the responses saved in separate files instead of sent to stdout. Use named globs:

curl -T "{<counter>one,two,three}.jpg" https://ul.example/ -o "save-#<counter>"

The only way to refer to an upload glob is to set a name and refer to that name. There are no indexed references for uploads, only for URL globs.

Mixing URL globs and uploads globs

It is in fact possible to also use a mix of upload globs and URL globs in the same command line if you want to upload multiple files to multiple destinations. They set the names in the same namespace and you refer to the names the same way, independently of source.

This feels more like a thing to show off in a blog post like this rather than something people will actually find good use for:

Upload three files to three sites, save all nine response in separate files:

curl -T "{<counter>one,two,three}.jpg" https://{<host>ul1,ul2,ul3}.example/ -o "save-#<counter>-#<host>"

Index and names

Even when you set a name, the glob can still also be references by its number.