Back to skill

Security audit

Swmm End To End

Security checks for vulnerabilities and agentic risk

Overview

The skill is a mostly coherent SWMM modeling orchestrator, but it asks agents to install and run external tooling and to persist audit notes outside the run directory by default.

Install only in a constrained project environment. Review the external Agentic SWMM repository, MCP package manifests, lockfiles, and install script before running npm install; prefer a container or unprivileged account. Disable Obsidian export unless you explicitly want run evidence copied to the named local vault.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:288
Finding

Unreviewed npm Dependency Installation with Lifecycle Script Execution

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:288-297
Vulnerability Type: Unsafe third-party dependency installation
Risk Level: Medium

Complete Code Snippet:

markdown
## Preflight
Before running any operating mode, every MCP server under `mcp/<server>/`
must have its `node_modules` installed. `node_modules/` is `.gitignored`,
so a fresh clone (or any server added later) needs an install step:

```bash
scripts/install_mcp_deps.sh                  # install for all mcp/*/ servers
scripts/install_mcp_deps.sh swmm-calibration # install for one server

The script loops over every mcp/*/package.json and runs npm install.

text

### Technical Analysis

The Skill makes dependency installation a mandatory preflight operation and states that `npm install` is run for every MCP server. By default, `npm install` can execute package lifecycle hooks such as `preinstall`, `install`, and `postinstall`. These hooks run as the user performing the installation and can execute arbitrary commands.

The audited package does not contain `scripts/install_mcp_deps.sh`, the referenced `package.json` files, or corresponding lockfiles. Consequently, the audit could not verify dependency names, pinned versions, integrity metadata, registry sources, or lifecycle scripts. The use of `npm install`, rather than a reproducible locked installation such as `npm ci`, may also permit dependency resolution to change between executions.

This creates a supply-chain trust boundary: the effective code executed during setup depends on external project content and packages that are not included in the reviewed artifact.

### Attack Path

1. An attacker compromises an npm dependency, publishes a malicious version within an accepted version range, or modifies an MCP server's package manifest or lockfile.
2. The user or Agent follows the mandatory preflight instruction and invokes `scripts/install_mcp_deps.sh`.
3. The instal
...[truncated 1071 chars]
Remediation
View remediation

Remediation Suggestions

  1. Include scripts/install_mcp_deps.sh, all relevant package.json files, and lockfiles in the reviewable project artifact.
  2. Commit a lockfile for every MCP server and replace npm install with npm ci to enforce reproducible dependency resolution.
  3. Use npm ci --ignore-scripts when lifecycle hooks are unnecessary.
  4. If lifecycle hooks are required, explicitly inventory and review each permitted hook before installation.
  5. Pin dependency versions and verify package integrity, provenance, registry origin, and publisher identity.
  6. Run dependency installation in a restricted container or unprivileged environment without access to production credentials or sensitive user files.
  7. Avoid automatically installing dependencies for every MCP server. Install only the server required for the selected workflow.
  8. Add automated supply-chain checks, including lockfile validation, dependency auditing, and detection of unexpected lifecycle scripts.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents this as an orchestration entrypoint for agentic SWMM modeling that determines tool ordering and stopping conditions across a workflow. The code does not implement such orchestration logic. Instead, it is a thin transport utility for invoking one MCP tool over stdio on a Node server. It initializes the server, lists available tools, checks that the requested tool exists, calls that one tool, and saves the response. While this could support an orchestration system, its primary purpose is materially narrower and different from the declared top-level orchestration behavior.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill directs broad shell execution, file writes, dependency installation, and script/CLI invocation but declares no explicit tool scope or permissions boundary. In an agent runtime, this creates an over-privileged orchestration surface where the agent may perform unintended local modifications or command execution beyond the user's immediate task.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The skill broadens itself from orchestration into direct script execution and transport verification, increasing the amount of executable behavior available to the agent. Expanding responsibility in this way weakens least-privilege boundaries and makes it easier for an orchestration entrypoint to perform unintended shell actions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs exporting audit notes to a default local Obsidian vault outside the run directory, creating filesystem side effects in a personal knowledge store. This can leak sensitive project details into an unrelated location, overwrite user notes, or persist data beyond the expected evidence boundary.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Defaulting to Obsidian export without a clear user-facing warning causes writes outside the expected workspace boundary. In agent settings, silent cross-directory writes are dangerous because users may assume artifacts remain confined to the run directory while the skill persists notes into a personal vault.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Recommending npm install during orchestration introduces package execution and supply-chain risk unrelated to the core modeling task. Dependency installation can run arbitrary lifecycle scripts, modify the local environment, and expand compromise impact if a package or lockfile is malicious or tampered with.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Hard-coding a personal vault location and enabling default export normalizes writing to a user-specific notes directory without prior confirmation. This increases the risk of privacy leakage, accidental persistence of sensitive operational data, and unexpected modification of personal knowledge-base contents.

Content

No source excerpt is available for this finding.

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 · scripts/mcp_stdio_call.py (reported line 22)May include surrounding context.

python
self.next_id = 1

    def __enter__(self) -> "McpStdioClient":
        self.proc = subprocess.Popen(
            ["node", "server.js"],
            cwd=self.server_dir,
            stdin=subprocess.PIPE,

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code launches node server.js via subprocess.Popen, which is a safety-relevant operation for code files under the missing-warning rule. Although the script prints a success summary afterward, there is no prior user-facing warning, confirmation prompt, or explanatory comment/docstring near the execution to disclose that it will start and interact with an external process.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

Creating directories and writing output to disk are file-modifying operations covered by the missing-warning rule for code files. While the argument name suggests an output path, this file does not include a confirmation prompt or explicit warning near the write explaining that it will create parent directories and write the raw response to disk.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.