T09 · Insecure Skill Coding Practices
Error
- Location
- server.py:189
- Finding
- Unvalidated Scan Parameters Permit Nmap Option and NSE Script Injection<![CDATA[ ## Vulnerability Details **File Location**: `server.py:189-195, 371, 392, 417-418, 471-472, 502-503, 535-536` **Vulnerability Type**: Nmap argument injection and unsafe NSE script selection **Risk Level**: High ### Vulnerable Code ```python def _nmap_structured(target: str, extra_args: list[str], timeout: int = 300) -> 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
- <![CDATA[ ## Remediation Suggestions 1. Validate port specifications with a strict parser rather than a permissive string check. Accept only individual integers from 1 through 65535, comma-separated lists, and correctly ordered numeric ranges. 2. Reject all whitespace, leading hyphens, empty components, path separators, and non-port tokens in `ports`. 3. Validate NSE script names against a conservative allowlist. If multiple scripts are permitted, parse a comma-separated list and validate each name independently. 4. Prohibit absolute paths, relative paths, `..`, path separators, whitespace, and option prefixes in `scripts`. 5. Apply centralized validation to every tool accepting `ports` or `scripts`, including TCP, SYN, UDP, service detection, script scanning, vulnerability scanning, and full reconnaissance. 6. Avoid joining arguments containing user input into a command string. Prefer an API that preserves a real argument vector through process execution. 7. If `python-nmap` requires an argument string, construct it only from validated, normalized values and use `shlex.join` where appropriate. 8. Run Nmap under a dedicated, minimally privileged account and restrict writable directories. 9. Add regression tests for whitespace-based option injection, script paths, output flags, data-directory flags, malformed port ranges, and leading-hyphen values. ]]>
