Back to skill

Security audit

MCP App Builder

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent MCP app builder, but its required template exposes a local tool server too broadly and recommends public tunneling without authentication guidance.

Install only if you are comfortable reviewing and hardening the generated server. Before exposing any MCP app outside localhost, bind to loopback by default, add authentication and per-tool authorization, restrict CORS, avoid public tunnels for sensitive data, and pin/audit the npm dependencies and any tunnel tooling.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
assets/mcp-app-template/server.ts:85
Finding
Unauthenticated MCP Endpoint Exposed on All Network Interfaces with Unrestricted CORS<![CDATA[ ## Vulnerability Details **File Location**: `assets/mcp-app-template/server.ts:85-102` **Additional Location**: `references/mcp-app-spec.md:161-178` **Vulnerability Type**: Missing authentication and overly permissive network access **Risk Level**: High ### Vulnerable Code ```ts const port = parseInt(process.env.PORT ?? "3001", 10); const app = createMcpExpressApp({ host: "0.0.0.0" }); app.use(cors()); app.all("/mcp", async (req, res) => { const server = createServer(); const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined, }); res.on("close", () => { transport.close().catch(() => {}); server.close().catch(() => {}); }); try { await server.connect(transport); await transport.handleRequest(req, res, req.body); ``` ### Technical Analysis The MCP server binds to `0.0.0.0`, making it reachable through every available network interface. The default `cors()` middleware accepts requests from arbitrary browser origins. No authentication, authorization, or caller identity validation occurs before the request is passed to `transport.handleRequest()`. The same implementation is presented as the required server pattern in `references/mcp-app-spec.md`, meaning applications generated from this Skill are likely to preserve the vulnerable configuration. Although the included sample tool only produces generated sample data, this is a scaffolding project intended to be customized with tools that may access databases, private APIs, files, or other sensitive services. Those tools would inherit the unauthenticated endpoint unless the developer adds controls separately. ### Attack Path 1. A developer creates an application from this template and starts the server. 2. The service binds to all network interfaces on the configured port. 3. The developer exposes the service through a public tunnel, cloud deployment, container port mapping, or reachable local network. 4. An attacker discovers or obtains ...[truncated 1015 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Bind to the loopback interface by default: ```ts const app = createMcpExpressApp({ host: "127.0.0.1" }); ``` 2. Require authentication before passing requests to the MCP transport. Validate a bearer token, signed request, mTLS client identity, or another deployment-appropriate credential. 3. Enforce authorization separately for each tool. A valid identity should only be allowed to invoke tools and access resources assigned to that identity. 4. Replace unrestricted CORS with an explicit allowlist: ```ts app.use(cors({ origin: ["https://trusted-client.example"], methods: ["GET", "POST", "DELETE"], })); ``` 5. Add rate limiting, request-body size limits, timeouts, and audit logging to reduce denial-of-service and abuse risks. 6. Update `references/mcp-app-spec.md` so public exposure is never presented without authentication, authorization, and origin restrictions. 7. If a tunnel is used for testing, configure access control at the tunnel layer and use a short-lived, non-production environment containing no sensitive credentials or data. ]]>

T08 · Insecure Dependencies

Warning
Location
references/mcp-app-spec.md:348
Finding
Unpinned Package Execution Through npx in Testing Instructions<![CDATA[ ## Vulnerability Details **File Location**: `references/mcp-app-spec.md:348` **Vulnerability Type**: Mutable third-party package execution **Risk Level**: Medium ### Vulnerable Code ```sh npx cloudflared tunnel --url http://127.0.0.1:3001 ``` ### Technical Analysis The testing workflow instructs users to execute `cloudflared` through `npx` without specifying an exact reviewed package version or integrity value. If the package is not already installed locally, `npx` may retrieve executable package content from the configured npm registry and run it with the developer's operating-system privileges. Because dependency resolution is mutable, the code executed at audit time may differ from the code executed later. Registry compromise, package-account compromise, malicious version publication, registry substitution, or configuration of an untrusted registry could therefore turn this instruction into a supply-chain execution path. The command also creates a public tunnel to the local MCP server. In the documented template, that server has no authentication and uses unrestricted CORS, so following the testing instructions can compound the network exposure described in the preceding finding. ### Attack Path 1. A developer follows the testing instructions and runs the documented `npx` command. 2. `npx` resolves the package using the developer's configured npm registry. 3. If no trusted local package is available, package content is downloaded at execution time. 4. Package lifecycle or runtime code executes as the developer's user account. 5. If the resolved package or registry response has been compromised, attacker-controlled code can access resources available to that account. 6. Independently, successful tunnel creation publishes the local MCP endpoint, making its unauthenticated tools reachable from the Internet. ### Impact Assessment A compromised package resolution can execute code with the privileges of the user running `npx`. Depending on the ...[truncated 584 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer the official Cloudflare binary installed through a trusted distribution channel and verify its signature or published checksum before use. 2. If npm-based execution is necessary, pin an exact reviewed version rather than resolving an unspecified current version. Record the dependency in a lockfile with integrity metadata and execute the locally installed binary. 3. Avoid commands that implicitly download and execute packages during routine testing. 4. Document the expected package source, version, checksum, and verification procedure. 5. Do not create a public tunnel until authentication and authorization are enabled on the MCP endpoint. 6. Protect test tunnels with an identity-aware access policy or equivalent tunnel-level authentication, and use short-lived credentials and isolated test data. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (25)

Ae1

High
Category
analysis-evasion
Content
p-template/` when possible, then customize tool names, schemas, and UI. Ensure `package.json` uses the exact versions, plus `tsconfig.json`, `vite.config.ts`, T
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The testing instructions recommend exposing a local MCP server through a public Cloudflare tunnel without any accompanying warning about data exposure, authentication, or limiting access. In the context of an app-builder skill, users may follow this verbatim and unintentionally publish development endpoints, tool functionality, or sensitive local data sources to the internet.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"dev": "npm run build && npm run serve"
  },
  "dependencies": {
    "@modelcontextprotocol/ext-apps": "^1.0.0",
    "@modelcontextprotocol/sdk": "^1.24.0",
    "zod": "^4.1.13",
    "react": "^18.3.1",
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
},
  "dependencies": {
    "@modelcontextprotocol/ext-apps": "^1.0.0",
    "@modelcontextprotocol/sdk": "^1.24.0",
    "zod": "^4.1.13",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unverifiable Dependency: @modelcontextprotocol/sdk has 3 known advisory(ies) (CVE-2026-25536 (@modelcontextprotocol/sdk has cross-client data leak via shared server/transport); CVE-2026-0621 (Anthropic's MCP TypeScript SDK has a ReDoS vulnerability); CVE-2025-66414 (Model Context Protocol (MCP) TypeScript SDK does not enable DNS rebinding protec)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"dependencies": {
    "@modelcontextprotocol/ext-apps": "^1.0.0",
    "@modelcontextprotocol/sdk": "^1.24.0",
    "zod": "^4.1.13",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "cors": "^2.8.5",
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unverifiable Dependency: zod has 1 known advisory(ies) (CVE-2023-4316 (Zod denial of service vulnerability)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"@modelcontextprotocol/ext-apps": "^1.0.0",
    "@modelcontextprotocol/sdk": "^1.24.0",
    "zod": "^4.1.13",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "cors": "^2.8.5",
    "express": "^5.1.0"
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unverifiable Dependency: react has 2 known advisory(ies) (CVE-2013-7035 (Cross-Site Scripting in react); GHSA-hg79-j56m-fxgv (Cross-Site Scripting in react)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"@modelcontextprotocol/sdk": "^1.24.0",
    "zod": "^4.1.13",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "cors": "^2.8.5",
    "express": "^5.1.0"
  },
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unverifiable Dependency: react-dom has 1 known advisory(ies) (CVE-2018-6341 (Cross-Site Scripting in react-dom)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"zod": "^4.1.13",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "cors": "^2.8.5",
    "express": "^5.1.0"
  },
  "devDependencies": {
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"react": "^18.3.1",
    "react-dom": "^18.3.1",
    "cors": "^2.8.5",
    "express": "^5.1.0"
  },
  "devDependencies": {
    "@vitejs/plugin-react": "^4.3.4",
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unverifiable Dependency: express has 5 known advisory(ies) (CVE-2024-10491 (Express ressource injection); CVE-2014-6393 (No Charset in Content-Type Header in express); CVE-2024-9266 (Express Open Redirect vulnerability) +2 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"express": "^5.1.0"
  },
  "devDependencies": {
    "@vitejs/plugin-react": "^4.3.4",
    "vite": "^6.0.0",
    "vite-plugin-singlefile": "^2.3.0",
    "tailwindcss": "^3.4.17",
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
},
  "devDependencies": {
    "@vitejs/plugin-react": "^4.3.4",
    "vite": "^6.0.0",
    "vite-plugin-singlefile": "^2.3.0",
    "tailwindcss": "^3.4.17",
    "autoprefixer": "^10.4.20",
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unverifiable Dependency: vite has 16 known advisory(ies) (CVE-2023-34092 (Vite Server Options (server.fs.deny) can be bypassed using double forward-slash ); CVE-2025-32395 (Vite has an `server.fs.deny` bypass with an invalid `request-target`); CVE-2025-31125 (Vite has a `server.fs.deny` bypassed for `inline` and `raw` with `?import` query) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"devDependencies": {
    "@vitejs/plugin-react": "^4.3.4",
    "vite": "^6.0.0",
    "vite-plugin-singlefile": "^2.3.0",
    "tailwindcss": "^3.4.17",
    "autoprefixer": "^10.4.20",
    "postcss": "^8.4.49",
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"@vitejs/plugin-react": "^4.3.4",
    "vite": "^6.0.0",
    "vite-plugin-singlefile": "^2.3.0",
    "tailwindcss": "^3.4.17",
    "autoprefixer": "^10.4.20",
    "postcss": "^8.4.49",
    "tsx": "^4.19.0",
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"vite": "^6.0.0",
    "vite-plugin-singlefile": "^2.3.0",
    "tailwindcss": "^3.4.17",
    "autoprefixer": "^10.4.20",
    "postcss": "^8.4.49",
    "tsx": "^4.19.0",
    "typescript": "^5.9.3"
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"vite-plugin-singlefile": "^2.3.0",
    "tailwindcss": "^3.4.17",
    "autoprefixer": "^10.4.20",
    "postcss": "^8.4.49",
    "tsx": "^4.19.0",
    "typescript": "^5.9.3"
  }
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unverifiable Dependency: postcss has 7 known advisory(ies) (CVE-2021-23382 (Regular Expression Denial of Service in postcss); CVE-2026-45623 (PostCSS: Arbitrary file read and information disclosure via attacker-controlled ); CVE-2023-44270 (PostCSS line return parsing error) +4 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"tailwindcss": "^3.4.17",
    "autoprefixer": "^10.4.20",
    "postcss": "^8.4.49",
    "tsx": "^4.19.0",
    "typescript": "^5.9.3"
  }
}
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"autoprefixer": "^10.4.20",
    "postcss": "^8.4.49",
    "tsx": "^4.19.0",
    "typescript": "^5.9.3"
  }
}
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Static analysis

No suspicious patterns detected.