CVE-2026-48684: FastNetMon NetFlow v9 Options Template Parser Walks Off the Packet | Lorikeet Security Skip to main content
Back to Blog

CVE-2026-48684: FastNetMon NetFlow v9 Options Template Parser Walks Off the Packet

Lorikeet Security Team May 23, 2026 8 min read
CVSS 7.5 -- High

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:


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


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

DateEvent
2026-04-25Vulnerability identified during Lorikeet Security source code audit of FastNetMon Community Edition 1.2.9
2026-04-25CVE ID requested from MITRE
2026-04-25Vendor (Pavel Odintsov / FastNetMon LTD) notified at the contact published in SECURITY.md
2026-05-22CVE-2026-48684 assigned by MITRE
TBDVendor response
TBDFix release
2026-05-23Lorikeet 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.

Download PDF

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.

-- views
Link copied!
Lorikeet Security

Lorikeet Security Team

Penetration Testing & Cybersecurity Consulting

Lorikeet Security helps modern engineering teams ship safer software. Our work spans web applications, APIs, cloud infrastructure, and AI-generated codebases — and everything we publish here comes from patterns we see in real client engagements.

Lory waving

Hi, I'm Lory! Need help finding the right service? Click to chat!