Back to skill

Security audit

nmap MCP server for AI-assisted network security auditing

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed nmap scanning tool, but it exposes high-impact network scanning with weak parameter and scope controls.

Install only in a dedicated, tightly scoped environment. Narrow allowed_cidrs before use, avoid hostname targets where possible, avoid nmap_custom_scan unless necessary, treat saved scan output as sensitive, and pin dependencies before production deployment.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
server.py:189
Finding

Unvalidated Scan Parameters Permit Nmap Option and NSE Script Injection

Content
View full analysis
dict: """ Run nmap with -oX - to get XML output, parse it with python-nmap, return a structured dict. """ nm = nmap.PortScanner() args_str = " ".join(extra_args) log.info("python-nmap scan: target=%s args=%s", target, args_str) try: nm.scan(hosts=target, arguments=args_str, timeout=timeout) ``` The following tool parameters are inserted into that argument string without validation: ```python result = _nmap_structured( target, ["-sT", "-p", ports, "-T4", "--open"], timeout=TIMEOUTS["standard"] ) ``` ```python result = _nmap_structured( target, ["--privileged", "-sU", "-p", ports, "-T4"], timeout=TIMEOUTS["deep"] ) ``` ```python port_args = ["--top-ports=1000"] if ports == "common" else ["-p", ports] extra = ["-sT", f"--script={scripts}", "-T4"] + port_args ``` Equivalent unvalidated `ports` handling also appears in service detection, vulnerability scanning, and full reconnaissance. ### Technical Analysis The public MCP tools accept `ports` and `scripts` as arbitrary strings. Although these values are initially placed in Python lists, `_nmap_structured` joins the entire list into a single string before passing it to `python-nmap`. Whitespace and option prefixes inside user-controlled values can therefore be interpreted as additional Nmap command-line options. The stricter checks implemented for `nmap_custom_scan`, including `_DANGEROUS_FLAGS`, are not applied to these tools. Consequently, an attacker can attempt to append output options, data-directory options, or NSE script selections through a crafted port value. The `scripts` parameter is particularly sensitive ...[truncated 2065 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
server.py:100
Finding

Hostname Scope Enforcement Is Vulnerable to DNS Rebinding

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Dependencies Are Installed Without Exact Version or Integrity Pinning

Content
View full analysis
=2.0.0 python-nmap>=0.7.1 pyyaml>=6.0 pytest>=7.0 # for running tests ``` The setup documentation also recommends unconstrained direct installation: ```bash pip install fastmcp python-nmap pyyaml ``` and: ```bash pip install -r requirements.txt ``` ### Technical Analysis All dependencies use open-ended lower bounds, and the direct installation command in `SKILL.md` does not impose even those minimum constraints. A future installation can therefore resolve to package versions that were not reviewed with this project. No integrity hashes are provided. The installation process consequently trusts the configured package index, package metadata, and whichever release is selected at installation time. If an upstream project, maintainer account, distribution channel, or package index is compromised, malicious build or package code may execute during installation or import. The audit did not identify a known malicious dependency in the listed package names. The finding concerns the absence of reproducible and integrity-verified dependency controls. ### Attack Path 1. A user follows the documented setup process. 2. `pip` queries the configured package index. 3. Because exact versions and hashes are absent, `pip` selects a mutable future release satisfying the lower bound, or any current release for the unconstrained command. 4. A compromised or malicious package release is downloaded. 5. Package build, installation, or import-time code executes with the privileges of the installing user or MCP server account. 6. The compromised dependency can access data and resources available to that account. This path depends on compromise or malicious publication in the dependency supply chain; no such compromise was establis ...[truncated 617 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (26)

Privileged Container / Container Escape

High
Category
Privilege Escalation
Confidence
80% confidence
Finding

Potential security issue detected. Manual review is recommended.

Content

Scanner excerpt · server.py (reported line 301)May include surrounding context.

python
"""
    _require_scope(target, "nmap_arp_discovery")
    # ARP discovery + privileged for raw socket access
    result = _nmap_structured(target, ["--privileged", "-sn", "-PR", "-T4"], timeout=TIMEOUTS["quick"])
    scan_id = _save_scan("nmap_arp_discovery", target, result)

    hosts = []

Privileged Container / Container Escape

High
Category
Privilege Escalation
Confidence
80% confidence
Finding

Potential security issue detected. Manual review is recommended.

Content

Scanner excerpt · server.py (reported line 346)May include surrounding context.

python
"""
    _require_scope(target, "nmap_arp_discovery")
    # ARP discovery + privileged for raw socket access
    result = _nmap_structured(target, ["--privileged", "-sn", "-PR", "-T4"], timeout=TIMEOUTS["quick"])
    scan_id = _save_scan("nmap_arp_discovery", target, result)

    hosts = []

Privileged Container / Container Escape

High
Category
Privilege Escalation
Confidence
80% confidence
Finding

Potential security issue detected. Manual review is recommended.

Content

Scanner excerpt · server.py (reported line 392)May include surrounding context.

python
"""
    _require_scope(target, "nmap_arp_discovery")
    # ARP discovery + privileged for raw socket access
    result = _nmap_structured(target, ["--privileged", "-sn", "-PR", "-T4"], timeout=TIMEOUTS["quick"])
    scan_id = _save_scan("nmap_arp_discovery", target, result)

    hosts = []

Privileged Container / Container Escape

High
Category
Privilege Escalation
Confidence
80% confidence
Finding

Potential security issue detected. Manual review is recommended.

Content

Scanner excerpt · server.py (reported line 441)May include surrounding context.

python
"""
    _require_scope(target, "nmap_arp_discovery")
    # ARP discovery + privileged for raw socket access
    result = _nmap_structured(target, ["--privileged", "-sn", "-PR", "-T4"], timeout=TIMEOUTS["quick"])
    scan_id = _save_scan("nmap_arp_discovery", target, result)

    hosts = []

Privileged Container / Container Escape

High
Category
Privilege Escalation
Confidence
80% confidence
Finding

Potential security issue detected. Manual review is recommended.

Content

Scanner excerpt · server.py (reported line 536)May include surrounding context.

python
"""
    _require_scope(target, "nmap_arp_discovery")
    # ARP discovery + privileged for raw socket access
    result = _nmap_structured(target, ["--privileged", "-sn", "-PR", "-T4"], timeout=TIMEOUTS["quick"])
    scan_id = _save_scan("nmap_arp_discovery", target, result)

    hosts = []

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · tests/test_nmap_mcp.py (reported line 161)May include surrounding context.

python
def test_get_scan_path_traversal_blocked(self):
        """nmap_get_scan must strip path traversal chars from scan_id."""
        result = json.loads(self.server.nmap_get_scan("../../etc/passwd"))
        self.assertIn("error", result)

    def test_list_scans_returns_records(self):

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
100% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_nmap_mcp.py (reported line 225)May include surrounding context.

python
def test_semicolon_rejected(self):
        with self.assertRaises(ValueError):
            self.server.nmap_custom_scan("127.0.0.1", "-sT -p 22; rm -rf /")

    def test_pipe_rejected(self):
        with self.assertRaises(ValueError):

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_nmap_mcp.py (reported line 225)May include surrounding context.

python
def test_semicolon_rejected(self):
        with self.assertRaises(ValueError):
            self.server.nmap_custom_scan("127.0.0.1", "-sT -p 22; rm -rf /")

    def test_pipe_rejected(self):
        with self.assertRaises(ValueError):

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
100% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_nmap_mcp.py (reported line 225)May include surrounding context.

python
def test_semicolon_rejected(self):
        with self.assertRaises(ValueError):
            self.server.nmap_custom_scan("127.0.0.1", "-sT -p 22; rm -rf /")

    def test_pipe_rejected(self):
        with self.assertRaises(ValueError):

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · tests/test_nmap_mcp.py (reported line 225)May include surrounding context.

python
def test_semicolon_rejected(self):
        with self.assertRaises(ValueError):
            self.server.nmap_custom_scan("127.0.0.1", "-sT -p 22; rm -rf /")

    def test_pipe_rejected(self):
        with self.assertRaises(ValueError):

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 75)May include surrounding context.

Required for SYN scans, OS detection, and ARP discovery. Only needs to be done once (redo after nmap upgrades):

bash
sudo setcap cap_net_raw+ep $(which nmap)

# Verify
getcap $(which nmap)

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill exposes network-scanning functionality and its setup/usage clearly implies shell execution, file access, and environment-variable usage, but it does not declare any explicit tool scope such as permissions or allowed-tools. In an agent environment, that omission weakens operator visibility and policy enforcement, making it easier for the skill to invoke powerful capabilities without clear guardrails.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The instructions tell users to grant cap_net_raw to the nmap binary, which increases the binary's privilege to open raw sockets, but they do not include a clear warning about the security implications. If nmap or a related execution path is abused, that added capability can enable more sensitive network operations than an unprivileged binary could perform.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 31)May include surrounding context.

md
# 2. Grant nmap raw socket capability (required for SYN + OS detection)
#    Only needs to be done once. Re-run after nmap upgrades.
sudo setcap cap_net_raw+ep $(which nmap)

# 3. Verify it worked
getcap $(which nmap)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · server.py (reported line 174)May include surrounding context.

python
cmd = [NMAP_BIN] + args
    log.info("Running: %s", " ".join(cmd))
    try:
        r = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
        return {
            "success": r.returncode == 0,
            "stdout": r.stdout,

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

The custom scan tool intentionally exposes broad nmap flag control to callers, and the current denylist only blocks some metacharacters and a subset of dangerous options. That still leaves a powerful recon capability that can run arbitrary nmap scan modes and potentially abusive NSE usage within allowed scope, which is risky in an agent context because tool access is not further permission-gated.

Content

Scanner excerpt · server.py (reported line 576)May include surrounding context.

python
_audit("nmap_custom_scan", target, {"flags": flags}, f"REJECTED: forbidden char", False)
            raise ValueError(f"Forbidden character in flags. Use individual tool functions for complex scans.")

    # Block flags that write to paths or execute arbitrary code
    # (nmap output flags, --script with path, --datadir, etc.)
    if _DANGEROUS_FLAGS.search(flags):
        _audit("nmap_custom_scan", target, {"flags": flags}, "REJECTED: dangerous flag", False)

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill persistently stores prior scan results, including targets, commands, findings, and raw outputs, and exposes them through list/retrieval tools without any access-control checks or ownership scoping. In a multi-user or shared agent environment, this can leak sensitive internal network data, vulnerability findings, and reconnaissance history to later users or sessions.

Content

No source excerpt is available for this finding.

Rp1

Low
Category
MCP Rug Pull
Confidence
60% confidence
Finding

pip install without ==version installs the latest release, which could include malicious changes.

Content

No source excerpt is available for this finding.

Rp1

Low
Category
MCP Rug Pull
Confidence
82% confidence
Finding

The setup instruction installs fastmcp without a pinned version, which makes builds non-reproducible and increases supply-chain risk if a future release introduces malicious code or breaking security changes. For infrastructure-facing software that executes scans and handles logs/files, dependency drift is a meaningful security concern.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency specification uses a lower-bound only constraint (fastmcp>=2.0.0), which permits installation of any future release, including vulnerable or breaking versions. In a security-sensitive skill that exposes network scanning capability and likely parses untrusted inputs/results, lack of pinning weakens supply-chain control and makes builds non-reproducible.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
fastmcp>=2.0.0
python-nmap>=0.7.1
pyyaml>=6.0
pytest>=7.0  # for running tests

Unverifiable Dependency: fastmcp has 14 known advisory(ies) (CVE-2025-69196 (FastMCP OAuth Proxy token reuse across MCP servers); GHSA-c2jp-c369-7pvx (FastMCP Auth Integration Allows for Confused Deputy Account Takeover); CVE-2025-64340 (FastMCP has a Command Injection vulnerability - Gemini CLI) +11 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
99% confidence
Finding

The manifest does not pin fastmcp, and the package is reported to have numerous known advisories, including high-risk authentication and command-injection issues. Because this skill is an MCP server for network scanning, a vulnerable fastmcp release could expose remote attack paths, privilege misuse, or command execution in a particularly sensitive operational context.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

python-nmap is specified with an unbounded minimum version, so deployments may resolve to different package versions over time, including versions with future vulnerabilities or incompatible behavior. Because this skill wraps nmap and likely handles external process interaction, dependency drift increases supply-chain and operational risk.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
fastmcp>=2.0.0
python-nmap>=0.7.1
pyyaml>=6.0
pytest>=7.0  # for running tests

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
99% confidence
Finding

PyYAML is unpinned despite being a historically sensitive package with multiple deserialization/input-handling advisories. Allowing any version >=6.0 makes it impossible to ensure that all installations use a reviewed safe release, which is especially risky if YAML is ever parsed from untrusted sources in the MCP server or its configuration.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
fastmcp>=2.0.0
python-nmap>=0.7.1
pyyaml>=6.0
pytest>=7.0  # for running tests

Unverifiable Dependency: pyyaml has 8 known advisory(ies) (CVE-2019-20477 (Deserialization of Untrusted Data in PyYAML); CVE-2020-1747 (Improper Input Validation in PyYAML); CVE-2020-14343 (Improper Input Validation in PyYAML) +5 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
97% confidence
Finding

PyYAML has a history of unsafe deserialization and input-validation issues, and the unpinned requirement prevents verification that deployed environments use a fixed version. If the skill consumes YAML configuration or external YAML content, a vulnerable PyYAML version could enable code execution or parser abuse.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.