A parsing flaw in the c-ares asynchronous DNS library, used by countless applications including Node.js and curl, can be exploited to crash software with a single malicious DNS response. The heap buffer overflow, tracked as CVE-2020-22217, was quietly patched by the open-source maintainers and picked up by Linux distributions, but many Windows applications that bundle the library are likely still vulnerable. If your organization runs network-facing services or desktop tools that rely on c-ares, you need to act now.
What Actually Happened: The SOA Parsing Bug
At the heart of CVE-2020-22217 is a classic unsafe parsing operation inside ares_parse_soa_reply(), the function responsible for decoding DNS Start of Authority (SOA) resource records. When c-ares receives a DNS reply, it processes each record according to rigid byte-by-byte rules. SOA records are particularly tricky: they contain variable-length domain names followed by fixed-width numeric fields. The vulnerable code failed to verify that the input buffer contained enough data to read the next field after advancing past a domain name. An attacker who controls a DNS server can craft a reply with a deliberately malformed SOA record, causing c-ares to over-read—or, in some configurations, write beyond—the allocated heap buffer.
According to the c-ares project’s GitHub issue tracker, the flaw was discovered through fuzzing, an automated testing technique that bombards parsers with random or mutated inputs to uncover crashes. The fix, committed upstream, adds a single bounds check: before the parser leaps to the next field, it now verifies that the remaining buffer length is at least large enough to hold the expected data. That minimal change, merged into c-ares version 1.17.0 and later, prevents the heap overflow entirely.
Who’s Affected? Windows Apps at Risk
c-ares is not a household name, but it’s woven into the fabric of modern software. On Windows, it often appears as a static library compiled directly into applications, making detection and patching far more difficult than updating a system DLL. Several high-profile projects depend on or have historically used c-ares:
- Node.js: Older versions of Node.js bundled c-ares for asynchronous DNS resolution. While recent Node.js releases have moved to a different DNS implementation, many enterprise applications and Electron-based desktop tools still ship with vulnerable Node.js runtimes.
- curl: The popular command-line HTTP tool and its associated libcurl library can be built with c-ares to enable non-blocking name lookups. Many Windows builds of curl, including those distributed with developer tools and package managers, link c-ares by default.
- Embedded runtimes and OEM software: Language runtimes (such as certain V8 or Chromium derivatives), networking appliances, and even some game engines have been known to incorporate c-ares for cross-platform DNS. Because the library is small and MIT-licensed, it’s often inserted into products without fanfare.
For everyday Windows users, the risk is indirect: if you run a chat client, a VPN, or a game that bundles a vulnerable c-ares, a malicious DNS reply can crash the application. For administrators and DevOps teams, the blast radius expands to any service or CI pipeline that processes DNS responses from untrusted upstream resolvers. A crash in a critical microservice connected to c-ares can cascade into outages.
How We Got Here: A Hidden Dependency with High Impact
The c-ares project originated as an embeddable, asynchronous DNS library for environments where the standard system resolver isn’t suitable—like event-driven network frameworks. Its clean C API and permissive license made it a go-to choice for developers who wanted to perform DNS lookups without blocking a thread. Over time, it was adopted by everything from media players to cloud SDKs.
The discovery of CVE-2020-22217 exposed a subtle but pervasive supply-chain risk. Parser bugs in foundational networking libraries are dangerous precisely because they sit at the boundary between trusted applications and untrusted network input. When the bug was publicly reported, a confusing discrepancy emerged in severity scores. The National Vulnerability Database assigned a CVSS base score of 5.9 (Medium), emphasizing denial of service (DoS). However, other trackers, including Amazon’s ALAS, gave it a critical 9.8 rating, pointing to the possibility of remote code execution (RCE) under certain memory layouts and compiler configurations.
That disagreement stems from differing assumptions about whether the overflow could be weaponized beyond a crash. In practice, for Windows environments where processes may lack modern heap hardening—or where a process runs with elevated privileges—the worst-case scenario could indeed allow an attacker to hijack control flow. Even a “mere” crash can be devastating: a single crafted DNS packet can repeatedly take down a service, requiring constant restarts and creating a denial-of-service condition that’s trivially exploited.
Adding to the headache, c-ares is often statically linked. Updating the operating system or even a package manager won’t fix a binary that ships with its own copy of the library. Developers must actively rebuild their applications against the patched version, and users must wait for updated installers.
What to Do Now: A Four-Step Fix for Windows Environments
1. Inventory every application that might carry c-ares
Start by hunting for vulnerable instances:
- Check Node.js deployments: Run node -p process.versions on your Node.js installations and look for the ares version string. If it’s pre‑1.17.0, it’s vulnerable. Note that Electron applications bundle their own Node.js runtime—list your installed Electron apps and verify each one.
- Examine curl installations: On Windows, curl --version often prints the DNS resolver backend. If you see “c-ares”, check the version number. Many Git for Windows distributions and third-party developer utilities include curl with c-ares.
- Scan for DLLs and executables: Use a tool like Sysinternals’ strings.exe or sigcheck.exe to search for “c-ares” strings in your application directories. Look for files such as cares.dll or libcares-2.dll. A quick PowerShell script can recursively inspect portable executables in program folders.
- Audit custom software: If your organization builds in-house tools, request a software bill of materials (SBOM) from developers or scan build trees with a dependency checker.
2. Apply patches and updates
Action depends on how you obtained the software:
- Applications with MSI or EXE installers: Check the vendor’s website for updated releases that bundle c-ares version 1.17.0 or later. If no update is available, contact the vendor with the CVE reference.
- Node.js installations: If you manage a specific Node version, consider upgrading to the latest LTS release, which no longer uses c-ares. For older Node installations that still depend on c-ares, you may need to replace the binary with a custom build (see step 3) or isolate the process from untrusted DNS.
- Windows Subsystem for Linux (WSL): If you run Linux applications under WSL, update your distribution’s packages: on Debian/Ubuntu, sudo apt update && sudo apt upgrade will pull in the patched libc-ares-dev and libc-ares2 packages if supported. On other WSL distros, use the native package manager.
3. Rebuild if you static-link c-ares
If your development team maintains an application that compiles c-ares directly into its binary, follow these steps:
- Grab the patched source from the c-ares repository (commit 1b98172b141fe874ad43e679e67506f9b2139043 or any later release tag).
- Recompile the library with the same flags and toolchain used previously. Ensure that your build process pulls in the corrected ares_parse_soa_reply.c.
- Re-run any existing fuzz tests—or, if you don’t have them, set up a quick fuzzing session with a tool like libFuzzer or AFL to validate that the vulnerable code path no longer triggers crashes.
- Re-sign and redeploy the rebuilt binaries to all affected endpoints.
4. Harden monitoring and restrict DNS exposure
While patches roll out, reduce the attack surface:
- Limit upstream DNS servers: Configure your network firewalls to allow DNS queries (UDP/TCP port 53) only to trusted resolvers you control. This prevents attackers from easily injecting malicious replies into your clients.
- Monitor for crashes: Set up alerting for any sudden increase in application crashes in your environment. On Windows, enable Application event logging for crashing processes and aggregate logs to a SIEM. Look for faulting module names that include “c-ares” or access violations in ares_parse_soa_reply.
- Use process mitigation policies: On Windows 10 and later, apply Exploit Protection settings to critical applications: enable Data Execution Prevention (DEP), force ASLR, and consider running the application in a restricted job object that limits child process creation and memory allocation.
Outlook: Why Parser Bugs Demand Better Supply Chain Hygiene
CVE-2020-22217 is a reminder that even a library smaller than a megabyte can become a single point of failure across thousands of products. The fix itself was trivial—one bounds check—but the real work lies in ensuring that the patched code reaches every embedded instance. Because c-ares is so frequently statically linked, the vulnerability will likely persist in legacy device firmware and older desktop applications for years.
For developers, the lesson is clear: treat parsers as hostile territory and invest in continuous fuzzing. For administrators, it’s time to demand SBOMs from vendors and to build inventory systems that track not just top-level applications but their transitive dependencies. Until then, a single malicious DNS packet will remain a cheap and effective way to disrupt business-critical software.