Two attacker-controlled length fields drive inner loops past the UDP packet boundary
- CVE
- CVE-2026-48684
- CVSS
- 7.5 (High)
- CWE
- CWE-125 (Out-of-bounds Read)
- Affected
- FastNetMon Community Edition <= 1.2.9
- Component
- src/netflow_plugin/netflow_v9_collector.cpp, lines 224-257 (function
process_netflow_v9_options_template) - Attack Vector
- Remote (NetFlow v9 UDP, default port 2055)
- Discovered by
- Lorikeet Security
NetFlow v9 distinguishes two kinds of templates: data templates, which describe the fields of a flow record, and options templates, which describe the fields of an options data record (metadata about the exporter, the sampling configuration, the export domain, and similar). The options template flowset is structurally more complex than a data template: it carries a separate "scope" section that identifies what entity the options apply to, followed by an "options" section that lists the metadata fields.
FastNetMon's process_netflow_v9_options_template() function parses both sections in two inner loops. Both loops walk records of type netflow9_template_flowset_record_t (4 bytes each: 2 bytes field type, 2 bytes field length). Both loops are driven by length fields that came in over UDP and are entirely attacker-controlled.
Disclosure status: Lorikeet Security notified FastNetMon LTD on April 25, 2026. CVE-2026-48684 was assigned by MITRE shortly thereafter. No vendor response or fix has been observed as of May 23, 2026. Apply the compensating controls below.
The bug
Both inner loops in process_netflow_v9_options_template() exhibit the same pattern: walk records until an attacker-controlled byte count is consumed, with no check that each individual read stays within the flowset boundary.
// Scope parsing loop -- lines 224-229
for (; scopes_offset < fast_ntoh(options_nested_header->option_scope_length);) {
netflow9_template_flowset_record_t* tmplr =
(netflow9_template_flowset_record_t*)(zone_address + scopes_offset);
// ^^^ OOB read: no check that (zone_address + scopes_offset + sizeof(*tmplr)) <= flowset_end
scopes_total_size += fast_ntoh(tmplr->length);
scopes_offset += sizeof(*tmplr);
}
// Options parsing loop -- lines 241-257
for (; options_offset < fast_ntoh(options_nested_header->option_length);) {
netflow9_template_flowset_record_t* tmplr =
(netflow9_template_flowset_record_t*)(zone_address + options_offset);
// ^^^ Same problem: no bounds check before dereference
options_total_size += fast_ntoh(tmplr->length);
options_offset += sizeof(*tmplr);
}
An attacker who installs an options template flowset with an inflated option_scope_length (or option_length) causes the loop to keep dereferencing 4-byte structures from memory past the end of the flowset, and eventually past the end of the entire UDP packet.
There is a second, subtler issue in the same loops: neither length field is validated to be a multiple of sizeof(netflow9_template_flowset_record_t). When the attacker supplies an option_scope_length that is not a multiple of 4, the loop reads the final record at an unaligned offset, and on platforms that do not gracefully handle unaligned reads, this can crash or produce silently wrong values. Even on x86 where unaligned reads "work," the resulting parsing state is inconsistent and downstream lookups may behave unpredictably.
Reachability
Identical to CVE-2026-48683: NetFlow v9 collector binds to 0.0.0.0:2055 by default, accepts unauthenticated UDP, and processes every received template flowset. The attacker needs only the ability to send UDP packets to the collector's port.
Crucially, this bug is reachable on the first packet from a new "source-id." An attacker does not need to install a separate data flowset first. A single crafted options template flowset is sufficient to trigger the OOB reads in both inner loops. The attack is one-packet, fire-and-forget.
Impact
The reachable impacts are the same as the data-flowset variant:
- Information disclosure. The 4-byte values read past the flowset boundary populate options-record fields that the collector stores and may export downstream. A patient attacker can map heap memory two bytes at a time (field-type, field-length) by carefully sizing inflated length fields and reading the resulting record content from downstream consumers or log files.
- Denial of service. Unaligned reads on platforms that signal SIGBUS for them crash the daemon outright. Reads past the page boundary of the UDP receive buffer that land on an unmapped page produce SIGSEGV.
- Type confusion in options-record consumers. Downstream code that uses the parsed options-record fields to look up exporter state, sampling rates, or export-domain configuration receives garbage values. Sampling-rate confusion is particularly harmful in DDoS detection because the rate is the multiplier on every observed packet count.
How a fix should look
// Before each dereference, verify the next sizeof(*tmplr) bytes are inside the flowset.
const uint8_t* flowset_end = zone_address + flowset_payload_length;
for (; scopes_offset < fast_ntoh(options_nested_header->option_scope_length);) {
if (zone_address + scopes_offset + sizeof(netflow9_template_flowset_record_t) > flowset_end) {
return false; // truncated options template -- discard
}
netflow9_template_flowset_record_t* tmplr =
(netflow9_template_flowset_record_t*)(zone_address + scopes_offset);
scopes_total_size += fast_ntoh(tmplr->length);
scopes_offset += sizeof(*tmplr);
}
Additionally validate the loop-driving length is a multiple of sizeof(*tmplr) at function entry. If the attacker sends an option_scope_length of 7 (not a multiple of 4), reject the whole flowset rather than tolerate the misalignment.
Mitigations until the fix ships
- Allowlist the NetFlow port at the firewall to your own router IPs. NetFlow v9 has no authentication; the firewall is the only meaningful access control.
- Bind the collector to a management interface rather than
0.0.0.0. Thenetflow_hostdirective infastnetmon.conftakes a specific bind address. - Run the daemon under
systemd-restartwithRestart=on-failureso a crash from an unaligned read does not leave you blind during an active attack. - Drop NetFlow v9 entirely if you don't need it. Many deployments only consume sFlow or IPFIX. Disabling the v9 collector by removing the
netflowplugin fromenable_protocol_plugineliminates this bug class for v9 specifically.
The takeaway
This is the third bounds-check omission in the FastNetMon parser family (alongside CVE-2026-48682 and CVE-2026-48683) and they all share the same shape: a length field arrives over the network, the parser trusts it, and an inner loop walks until that length is consumed without checking each iteration against the actual buffer boundary. The fact that all three exist in the same codebase points at a missing architectural invariant: there is no shared "safe walk" helper that the parser code uses, so every loop has to remember the bounds check on its own, and inevitably some don't.
For codebases that handle this much wire-format parsing, the right fix is structural — a BoundedReader abstraction that owns the buffer end pointer and refuses to advance past it — not just a tactical bounds check added to each loop. The tactical fix closes this CVE; the structural fix prevents the next one.
Disclosure timeline
| Date | Event |
|---|---|
| 2026-04-25 | Vulnerability identified during Lorikeet Security source code audit of FastNetMon Community Edition 1.2.9 |
| 2026-04-25 | CVE ID requested from MITRE |
| 2026-04-25 | Vendor (Pavel Odintsov / FastNetMon LTD) notified at the contact published in SECURITY.md |
| 2026-05-22 | CVE-2026-48684 assigned by MITRE |
| TBD | Vendor response |
| TBD | Fix release |
| 2026-05-23 | Lorikeet Security publishes responsible disclosure report |
Full Responsible Disclosure Report (PDF)
Complete writeup of all 16 FastNetMon Community Edition vulnerabilities Lorikeet Security identified, including vulnerable-code excerpts, impact analysis, and remediation guidance for each CVE.
Auditing the network infrastructure your business depends on
Lorikeet Security finds the parser bugs, protocol confusion, and unauthenticated-control-plane issues that move your DDoS detector, your BGP speaker, and your edge devices from "running" to "exploitable." Source code review, fuzz harness development, and adversarial protocol testing.