A pre-authentication vulnerability in TDengine, a time-series database used across industrial telemetry, energy, utilities, connected vehicles, and IoT environments, allows an unauthenticated attacker to crash the database with a single malformed packet.
Discovered by the Ridge Security Research Team
The Problem, in Plain Terms
Time-series databases are the quiet workhorses of modern infrastructure. They sit behind factory-floor SCADA systems, EV charging networks, building automation, telecom monitoring, and the dashboards that tell an operations team whether anything is on fire. They are chosen often by threat actor because they ingest enormous volumes of machine data. And because they are internal plumbing rather than customer-facing applications, they are often deployed the way plumbing is deployed: once, correctly, and then left alone.
That combination critical to operations, invisible to the people who own risk is what makes a vulnerability like this one worth paying attention to. The Ridge Security Threat Research Team identified a flaw in TDengine, a widely deployed open-source distributed time-series database, that allows an unauthenticated remote attacker to crash the database server with a single malformed network packet. No credentials. No valid session. No user interaction. One packet, and the process is gone.
Tracked as CVE-2026-42542 and rated CVSS 7.5 (High), the issue has been reported to the TDengine maintainers under coordinated disclosure and is fixed in version 3.4.1.6. Versions 3.4.0.0 through 3.4.1.5 are affected. If you run TDengine, the short version of this post is: upgrade to 3.4.1.6 or later, and make sure port 6030 is not reachable from anywhere it does not need to be.
The longer version is more interesting, because the root cause is a category of bug that keeps resurfacing across the industry — a bug that is not about missing authentication or a forgotten access-control check, but about arithmetic.
What Actually Goes Wrong
TDengine’s server component, taosd, speaks a custom binary RPC protocol on TCP port 6030 by default. Every message on that wire begins with a fixed-size header, STransMsgHead, and the header carries a length field — msgLen — that tells the server how large the rest of the message is.
Early in connection handling, before any authentication has taken place, the server calls a function named uvConnMayGetUserInfo() to pull the user identity out of the inbound message. To do that, it needs to work out how many bytes of payload follow the header. It does what looks like the obvious thing: it subtracts the header size from the message length.
That subtraction is where it falls apart.
The length value is a signed 32-bit integer taken directly from the attacker-controlled msgLen field. The header size is an unsigned size_t. In C, when you mix those two types in an arithmetic expression, the signed value is promoted to unsigned. So if an attacker supplies a msgLen that is smaller than the required offset — typically 64 or 192 bytes, depending on the message variant — the subtraction does not produce a sensible negative number that later code can reject. It wraps around to an enormous positive value — on a 64-bit system, something close to 2^64.
That astronomically large value is then handed to memcpy() as a length.
The result is exactly what you would expect: memcpy() charges off the end of the heap allocation and the process dies with a segmentation fault. The database is down. The attacker spent one packet and needed no credentials to send it.
The fix, as is often the case with this class of bug, is unglamorous and about three lines long: validate that the message length is at least as large as the header plus the offset before doing any arithmetic on it. That validation now exists at the top of uvConnMayGetUserInfo() in 3.4.1.6.
Why This Class of Bug Is Worth Attention
Integer underflow in a length calculation is not a novel vulnerability class. It is, in fact, one of the oldest. What makes it durable is that it hides in code that looks completely reasonable. length – header_size is not a suspicious line. It does not light up in code review. It only becomes a vulnerability when you notice that one operand is signed, the other is unsigned, and the first one comes from a stranger on the network.
There is a second lesson layered underneath the first: this code runs before authentication. The parsing logic that extracts user identity necessarily executes prior to verifying that identity. That is an unavoidable property of protocol design — you have to read the credentials before you can check them — but it means the pre-authentication parsing surface of any network service is, by definition, exposed to anyone who can reach the port. Every byte of parsing that happens before the auth check is attack surface available to the entire internet.
When we audit network daemons, that pre-auth parsing path is the first place we look. It is where the ratio of attacker reward to attacker effort is highest.
Impact: What an Attacker Gets
Confirmed impact is denial of service. A single crafted packet to the RPC port reliably crashes taosd. If the service is under a supervisor or systemd restart policy, it comes back — and an attacker can simply send the packet again, in a loop, holding the database in a permanent crash cycle. For a time-series database, a crash is not a clean failure: in-flight writes are lost, and for an operational-technology or telemetry workload, lost writes are lost visibility. A monitoring system that is down is also a monitoring system that is not alerting.
Memory corruption is the underlying primitive, and that raises a harder question. The bug is a heap buffer overflow driven by an attacker-influenced length. Historically, that class of primitive has sometimes been developed into remote code execution. We are not claiming RCE here, instead it is “confirmed unauthenticated remote DoS with heap corruption as the underlying mechanism,” and that defenders should size their response to the corruption primitive, not just to the crash.
Who Should Care
TDengine’s design center is IoT, industrial telemetry, connected vehicles, energy and utilities, and large-scale device monitoring. Those are the deployments most likely to be affected, and they share an uncomfortable pair of properties: the data is operationally critical, and the maintenance windows are narrow or nonexistent.
Organizations most exposed tend to be those where:
- TDengine sits on a flat OT or device network where “internal” means reachable by a great many hosts
- The database was deployed by an integrator or bundled inside a vendor appliance, and the operating team may not know it is there
- Uptime requirements make patching a scheduled, quarterly event rather than a same-week one
What To Do
1. Upgrade to TDengine 3.4.1.6 or later. This is the actual fix. Everything else is a stopgap.
2. If you cannot patch immediately, reduce reachability. Port 6030 should not be exposed to the internet, and in most architectures it should not be broadly reachable inside the network either. Restrict it with host firewall rules or network ACLs to the specific application hosts that need to talk to it. This vulnerability requires network access to the RPC port; removing that access removes the exposure, patched or not.
3. Inventory before you assume. Check whether TDengine is present in bundled or OEM products in your environment. Embedded deployments are the ones that get missed.
4. Watch for the crash signature. See the detection section below.
Beyond the Zero-Day: Cryptographic Observations
While auditing the same code paths, the team noted two areas where TDengine’s cryptographic posture lags current practice. Neither is a vulnerability in the CVE sense, and neither is part of CVE-2026-42542 — but both are worth raising with the community:
- Password hashing defaults to MD5. MD5 has been considered cryptographically broken for years and offers effectively no resistance to offline dictionary or rainbow-table attacks against a captured credential store. Modern practice is a memory-hard, salted algorithm — Argon2id or bcrypt.
- RPC connection signatures use SHA-1. SHA-1 is deprecated for collision resistance and should be moved to SHA-256.
It is worth balancing this with credit where it is due: TDengine’s codebase shows genuinely defensive habits elsewhere, including a disciplined internal tstrncpy() wrapper for string handling. The weakness is not carelessness across the board. It is concentrated at the network boundary, which is exactly where it hurts most — and that pattern is far more common across the industry than most engineering teams would like to admit.
Detection Guidance
We want to be straightforward about the limits of what we can offer here: Ridge Security has no telemetry indicating in-the-wild exploitation of this vulnerability, and we are not aware of any public exploit code. We are not going to manufacture indicators of compromise we have not observed. What follows is detection logic derived from the mechanics of the bug, not from observed attacks.
Because the vulnerability is a crash rather than an implant, the signal is behavioral:
- Unexplained taosd segmentation faults, particularly repeated ones. Check dmesg, the kernel journal, and any core-dump collection for taosd crashes. Repeated segfaults on a service that had been stable are the primary indicator.
- Restart loops. If a supervisor or systemd unit is restarting taosd repeatedly, treat that as a security event until proven otherwise, not merely a stability issue.
- Connection attempts to port 6030 from unexpected sources, especially short-lived connections that send a small amount of data and do not establish a session. Correlating inbound connections to 6030 against your known client inventory is worth doing regardless of this CVE.
- Gaps in time-series ingestion. A sudden hole in your own metrics is, ironically, one of the clearest symptoms of a downed metrics database.
A defender writing a network signature has a reasonably clean anchor: a packet to the RPC port whose declared msgLen is smaller than the fixed header size is never legitimate traffic.
On the Proof of Concept
Ridge Security has a working proof of concept. In keeping with fair-disclosure practice, we are not publishing it. The technical description above is deliberately specific enough that an informed reviewer can confirm the finding is genuine, and deliberately short of a working exploit.
We will share the full PoC with vetted security teams — vendors, CERTs, and enterprise defenders who need it for validation or detection engineering — under an agreement not to redistribute it publicly. Teams that need it can reach us through the contact information below.
Disclosure Timeline
The issue was reported to the TDengine maintainers through coordinated disclosure. The maintainers were responsive, the root cause was confirmed, and a fix shipped in 3.4.1.6 with a published advisory. We want to note that explicitly: this is what a well-handled disclosure looks like from the researcher’s side, and the TDengine team deserves credit for it.
Full advisory: GHSA-vg95-j2hf-hvjx
A Second Finding: CVE-2026-44639
In separate research, the team also identified CVE-2026-44639 in NanoMQ, a widely used lightweight MQTT broker. The broker’s MQTT v5 property decoder walks the entire property linked list for each property appended, producing O(N²) behavior. An unauthenticated attacker who sends PUBLISH or SUBSCRIBE packets carrying a large number of User Properties can drive CPU consumption high enough to make the broker unresponsive.
It is a materially less severe issue — CVSS 3.7 (Low), resource exhaustion rather than memory corruption — and it is fixed in NanoMQ 0.24.14. We mention it because it rhymes with the first finding in a way that is worth noticing: both are unauthenticated, both live in the message-parsing path, and both are algorithmic or arithmetic mistakes rather than missing security controls. The parsing layer of a network service is where a surprising share of real risk lives.
The Takeaway
The infrastructure that carries machine data is now as security-relevant as the applications that sit on top of it, and it is inspected far less often. CVE-2026-42542 is a three-line fix guarding a subtraction, in a function that runs before anyone has proven who they are, on a port that in too many networks is reachable from too many places. That is not an exotic failure. It is an ordinary one, in an important place.
Patch to 3.4.1.6, put an ACL in front of port 6030, and go find out how many time-series databases are actually running in your environment. Most organizations are surprised by the answer.
The Ridge Security Threat Research Team conducts independent vulnerability research across enterprise, infrastructure, and open-source software — combining source and binary-level auditing with dynamic validation in isolated environments — and discloses every finding under coordinated disclosure. Research credit: Yan Zhou, Ridge Security.
