CVE-2026-48687: OS Command Injection in FastNetMon Juniper Plugin Logging | Lorikeet Security Skip to main content
Back to Blog

CVE-2026-48687: OS Command Injection in FastNetMon's Juniper Plugin Logging Function

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

PHP exec() Called With Unsanitized Attack Data — Shell Metacharacters Run as Commands

CVE
CVE-2026-48687
CVSS
8.1 (High)
CWE
CWE-78 (OS Command Injection)
Affected
FastNetMon Community Edition <= 1.2.9
Component
src/juniper_plugin/fastnetmon_juniper.php, function _log(), lines 115-119
Attack Vector
Indirect remote (via the attack notification pipeline)
Discovered by
Lorikeet Security

FastNetMon ships with a number of "notification scripts" that integrate the detector with router platforms for automated mitigation. The Juniper plugin (src/juniper_plugin/fastnetmon_juniper.php) is a PHP script that FastNetMon invokes when an attack is detected, with command-line arguments containing the attacker's IP address, the direction of the attack, and the traffic rate. The script then pushes a Juniper NETCONF configuration change to add a discard route for the attacking IP, plus logs a message recording the action.

The logging function, _log(), accepts a message string and writes it to a temporary log file using exec("echo `date` \"- [FASTNETMON] - $msg \" >> $FILE_LOG_TMP"). The $msg parameter is built by interpolating the script's command-line arguments — the attack IP, direction, and power values — into a status string. Those arguments are not sanitized, and PHP's exec() runs the entire concatenated string through /bin/sh. Any shell metacharacter in the attack data turns into command execution.

Disclosure status: Lorikeet Security notified FastNetMon LTD on April 25, 2026. CVE-2026-48687 was assigned by MITRE. No vendor response or fix as of May 23, 2026.


The vulnerable code

// src/juniper_plugin/fastnetmon_juniper.php, lines 115-119
function _log( $msg ) {
    $FILE_LOG_TMP = "/tmp/fastnetmon_api_juniper.log";
    exec( "echo `date` \"- [FASTNETMON] - " . $msg . " \" >> " . $FILE_LOG_TMP );
}

// Earlier in the same file:
$IP_ATTACK = $argv[1];
$DIRECTION_ATTACK = $argv[2];
$POWER_ATTACK = $argv[3];
// ...
_log("Ban: IP=$IP_ATTACK direction=$DIRECTION_ATTACK power=$POWER_ATTACK");

The pattern is exactly the textbook shell injection: untrusted input concatenated into a shell command string, passed to exec() without escaping. If any of $IP_ATTACK, $DIRECTION_ATTACK, or $POWER_ATTACK contain backticks, $( ), semicolons, or newlines, the resulting shell command parses and executes them.

Why $IP_ATTACK is attacker-influenceable

You might object that $IP_ATTACK comes from FastNetMon's C++ core, which currently passes IP addresses via inet_ntoa() — a function that only produces well-formed dotted-decimal output. That's true today. It is not true in general:

The current FastNetMon code happens to pass safe values today, but the vulnerability is in the script, not in the caller. Defensive coding requires the script to validate or escape its own inputs — the surrounding system's invariants can change, and they will.


Exploit example

If an attacker can supply a value for $IP_ATTACK that contains shell metacharacters — say, 1.2.3.4`id>/tmp/owned` — the log line becomes:

echo `date` "- [FASTNETMON] - Ban: IP=1.2.3.4`id>/tmp/owned` direction=in power=1000 " >> /tmp/fastnetmon_api_juniper.log

The shell sees the backticks, runs id, captures its output, and substitutes it into the echo string. As a side effect, id's output is written to /tmp/owned. Substitute any command you want; the same mechanism executes it.

The impact runs as whoever executes the PHP script. In production deployments, this is typically the FastNetMon process user, which is often root because of the raw-packet-capture requirement. Even on hardened deployments where FastNetMon runs as a low-privilege user, the notify script frequently runs as root via sudo (because it needs to push NETCONF configuration to a router), which makes the injection a privilege escalation.


How a fix should look

There are two correct fixes. The first replaces exec() with PHP's native file API, which has no shell involvement:

function _log( $msg ) {
    $FILE_LOG_TMP = "/tmp/fastnetmon_api_juniper.log";
    $timestamp = date("Y-m-d H:i:s");
    file_put_contents(
        $FILE_LOG_TMP,
        "$timestamp - [FASTNETMON] - $msg\n",
        FILE_APPEND | LOCK_EX
    );
}

No shell, no exec, no metacharacter problem. This is the recommended fix — you don't need a shell to append a line to a file. The original code probably used exec("echo ... >> file") because date was easier to reach via shell substitution than via PHP's date function. file_put_contents() with a PHP-native timestamp is the modern idiom.

The second correct fix, if for some reason you must use exec, is to escape every interpolated value:

function _log( $msg ) {
    $FILE_LOG_TMP = "/tmp/fastnetmon_api_juniper.log";
    $escaped = escapeshellarg($msg);
    exec( "echo `date` " . $escaped . " >> " . escapeshellarg($FILE_LOG_TMP) );
}

escapeshellarg() wraps the value in single quotes and escapes any embedded single quotes, neutralizing shell metacharacters. This is more brittle than the file API because every concatenation has to remember to escape; one missed call site reintroduces the bug. Prefer the file-API form.


Compensating controls


The pattern: notify scripts are security-relevant

This is the third command-injection bug we've seen in this disclosure series (alongside CVE-2026-48694 and CVE-2026-48695), all in the notify-script family. There is a recurring assumption in DDoS-mitigation tooling that notify scripts are "internal" and therefore don't need the same input validation as user-facing code. That assumption is wrong for at least three reasons:

  1. Scripts that take input from network observations are taking attacker input. The whole point of the notify script is to react to an external attack. The data being reacted to comes from the attacker. There is no internal vs. external boundary at the point where the script reads its argv.
  2. Scripts get invoked from places nobody anticipated. Operators write wrappers, cron jobs invoke the binaries with parsed parameters, monitoring systems trigger test runs. Every additional invocation path is a new input source.
  3. Scripts often run with elevated privileges. They push configuration to routers, modify firewall rules, restart services. Sudo wrappers and setuid wrappers are common. The privilege concentration in notify scripts is high; the security review of them is usually low.

The fix for the class is to treat notify scripts as exposed surface and write them defensively from the start: validate inputs against strict formats (IP regex for IPs, integer regex for rates, whitelisted enums for directions), use language-native APIs instead of shelling out, and run them as low-privilege users. Treat them like CGI scripts — because that's effectively what they are.


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-48687 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!