curl is one of the most trusted tools for fetching data from the internet, widely used in scripts, apps, and developer workflows. Its reliability is key to the security of millions of systems. In 2022, a subtle but dangerous bug (CVE-2022-42916) was discovered in how curl handled Host-based HSTS protection, opening the door for attacks that could trick users into thinking their connection was secure—when it wasn’t.

This post breaks down, in plain English, exactly what happened, how it was exploited using tricky Unicode hostnames, provides code examples, and shows how you can stay safe.

A Quick Primer: What’s HSTS?

HTTP Strict Transport Security (HSTS) is a way for a website to tell browsers and clients: *“Always use HTTPS when talking to me, even if the user tries to start on regular old HTTP.”* This stops attackers from intercepting or modifying traffic, because secure HTTPS is always forced.

Since curl 7.77. (May 2021), curl also supports HSTS. It remembers sites that told it “always use HTTPS,” and upgrades your future requests from http://example.com to https://example.com, even if you meant to use old, insecure HTTP.

The Problem: Tricking curl with Special Hostnames

You’d expect that if curl knows to always upgrade http://example.com to HTTPS, it also will do the same for http://example。com (notice the special dot).

But in reality, curl before 7.86. didn't recognize that example.com and example。com could be the same site, due to the way it handled Internationalized Domain Names (IDNs) using special Unicode dots.

What’s the Unicode Dot About?

Normally, a host is split up with the classic period or "full stop" (ASCII . — U+002E). However, in Unicode, there’s another lookalike: U+3002, IDEOGRAPHIC FULL STOP (). Some browsers treat them as equivalent in domains.

So, an attacker can register example。com (with the Unicode dot instead of a regular period) and trick applications that don’t properly normalize the hostname.

Exploiting CVE-2022-42916

In curl versions >= 7.77. and < 7.86., HSTS entries are stored *after* converting a domain with Unicode dots (U+3002) into an ASCII domain, but the check for if the domain is already HSTS was done *before* converting.

This means

1. You visit https://example.com, which returns an HSTS header. curl remembers example.com as HSTS.
2. Next, an attacker tricks you into visiting http://example。com (the Unicode full stop).
3. curl checks: “Is example。com (Unicode dot) on my HSTS list?” It doesn’t find it—since that’s not normalized.

Example Exploit in Practice

Here’s a quick demo. Let’s assume the attacker controls example。com and tricks a user.

Suppose your ~/.curlhsts file has the entry

example.com 1 197-01-01T00:00:00Z

Attacker URL

curl http://example。com

Note: The domain here is example + U+3002 + com.

Quick Python Example of the Problem

Here's a short demonstration in Python (not curl code, but it'll show the kind of error that happens):

def is_hsts_domain(hsts_domains, domain):
    # In curl <7.86., the check is BEFORE idn conversion:
    return domain in hsts_domains

hsts_domains = {'example.com'}  # HSTS remembers the ASCII name

# User inputs Unicode domain with ideographic full stop
user_domain = 'example。com'  # note: '。' is U+3002

print(is_hsts_domain(hsts_domains, user_domain))  # False -- problem!

curl 7.77. (May 26, 2021) – 7.86. (Before October 26, 2022)

- Any scripts, automation, or apps using curl’s HSTS support with IDN/Unicode hostnames.

Original References

- curl Security Advisory on CVE-2022-42916
- curl Changelog 7.86.
- CVE Details Page
- curl HSTS documentation

Real-World Impact

This attack isn't just theoretical. If an attacker can trick you into visiting a "lookalike" domain (with an IDN dot), your connection could drop back to HTTP—even if you’d previously visited the real secure site, and curl knew to always use HTTPS.

For example, a script processing user-provided links or domain lists might fetch with curl—and not realize it's connecting in an insecure way.

How Was This Fixed?

Starting with curl 7.86., released October 26, 2022, the hostname check normalizes IDN domains before doing the HSTS check. Now, example.com and example。com are matched properly, and the bypass is gone.

Fix Example (Pseudo-Code)

// Pseudocode example based on the fix
char *normalized_host = idn_convert(host);
if(hsts_check(normalized_host)) {
    // Enforce HTTPS
}

Be careful with IDN domains: Even with the fix, lookalike domains can be used for phishing.

- Check your automation and scripts: If you rely on curl’s HSTS support, double-check that dependencies are up to date.

Check Your curl Version

curl --version


Look for libcurl version 7.86. or higher.

Summary

CVE-2022-42916 is a reminder that even small details—like Unicode full stops—can have big security consequences. By letting attackers bypass automatic HTTPS upgrades with trick domain names, the bug put users at risk of man-in-the-middle attacks. The fix was straightforward: normalize first, check second.

As always, keep your software up-to-date, and watch out for domains that look a little "off"!

Further Reading

- curl official HSTS docs
 - Unicode Security Guide
 - How browsers handle IDN homographs

Timeline

Published on: 10/29/2022 02:15:00 UTC
Last modified on: 11/14/2022 15:16:00 UTC