Back to skill

Security audit

Teller MCP – Borrow USDC & Altcoins (no margin calls)

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent Teller MCP integration, but it returns ready-to-submit financial blockchain transactions from a remote API without enough validation, scoping, or user safety warnings.

Review this skill before installing. Use it only with a trusted Teller API endpoint, treat wallet addresses and loan IDs as sensitive financial metadata, and never let an agent or wallet auto-sign the returned borrow or repay transactions without independently checking the chain, destination contracts, calldata, amounts, allowances, and native value. Update or constrain dependencies before production use.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/tellermcp-server/src/client.ts:71
Finding
Unvalidated Remote Transaction Calldata Exposed as Ready-to-Submit Transactions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/tellermcp-server/src/client.ts:71-132`; related exposure in `scripts/tellermcp-server/src/index.ts:143-180, 204-227` **Vulnerability Type**: Insufficient validation of security-sensitive remote API responses **Risk Level**: High ### Vulnerable Code ```ts getBorrowTransactions(params: { walletAddress: string; collateralTokenAddress: string; chainId: number; poolAddress: string; collateralAmount: string; principalAmount: string; loanDuration?: number; }): Promise<BorrowTransactionsResponse> { return this.request<BorrowTransactionsResponse>('/borrow-tx', { walletAddress: params.walletAddress, collateralTokenAddress: params.collateralTokenAddress, chainId: params.chainId, poolAddress: params.poolAddress, collateralAmount: params.collateralAmount, principalAmount: params.principalAmount, loanDuration: params.loanDuration }); } getLoans(params: { walletAddress: string; chainId: number }): Promise<LoansResponse> { return this.request<LoansResponse>('/loans/get-all', { walletAddress: params.walletAddress, chainId: params.chainId }); } getRepayTransactions(params: { bidId: number; chainId: number; walletAddress: string; amount?: string }): Promise<RepayTransactionsResponse> { return this.request<RepayTransactionsResponse>('/loans/repay-tx', { bidId: params.bidId, chainId: params.chainId, walletAddress: params.walletAddress, amount: params.amount }); } private async request<T>(path: string, query?: Record<string, string | number | boolean | undefined>): Promise<T> { const url = new URL(path, this.baseUrl); if (query) { for (const [key, value] of Object.entries(query)) { if (value === undefined || value === null || value === '') continue; url.searchParams.set(key, String(value)); } } const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), this.timeoutMs); t ...[truncated 4710 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Apply strict runtime response validation** - Define strict Zod schemas for borrow and repayment transaction responses. - Reject missing, malformed, additional, or incorrectly typed fields. - Enforce Ethereum address and hexadecimal calldata formats. - Limit transaction counts and response sizes. 2. **Verify transaction semantics** - Maintain an allowlist of Teller contracts for each supported chain. - Verify that every `to` address belongs to the selected chain and expected Teller deployment. - Decode calldata and allow only expected function selectors. - Confirm that approval spenders, tokens, recipients, loan IDs, pool addresses, and amounts match the original request. - Reject unexpected native-currency values and unrelated contract calls. - Apply conservative approval limits rather than accepting arbitrary or unlimited approvals. 3. **Restrict API origins** - Require HTTPS outside explicit local-development mode. - Allowlist trusted production hostnames. - Reject URLs containing credentials and unapproved ports or protocols. - Treat changes to `TELLER_API_BASE_URL` as security-sensitive configuration. 4. **Require informed transaction confirmation** - Decode and display each transaction’s destination, method, token, spender, amount, and native value. - Require explicit human confirmation before any signature or broadcast. - Clearly label API-generated calldata as untrusted until locally verified. - Remove documentation stating that remote results should be used directly. 5. **Strengthen request validation** - Require amount strings to match a decimal base-unit format such as `^(0|[1-9][0-9]*)$`. - Enforce nonzero and protocol-appropriate upper bounds. - Validate supported chain IDs and reasonable loan-duration limits. 6. **Fail closed** - If contract metadata, selector decoding, chain information, or response validation cannot be completed, do not re ...[truncated 48 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (22)

Ae1

High
Category
analysis-evasion
Content
- `package.json` / `package-lock.json` – Node 20+ project metadata
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Known Vulnerable Dependency: @hono/node-server==1.19.9 — 3 advisory(ies): CVE-2026-39406 (@hono/node-server: Middleware bypass via repeated slashes in serveStatic); GHSA-frvp-7c67-39w9 (Node.js Adapter for Hono: Path traversal in `serve-static` on Windows via encode); CVE-2026-29087 (@hono/node-server has authorization bypass for protected static paths via encode)

High
Category
Supply Chain
Confidence
94% confidence
Finding
The lockfile pins @hono/node-server 1.19.9, and the cited advisories describe path traversal and authorization/middleware bypass issues in static file serving. Even though this file is only a dependency manifest, including a known vulnerable server component is a real supply-chain risk because the MCP SDK depends on it and an exposed MCP backend may process HTTP paths from remote clients.

Known Vulnerable Dependency: express-rate-limit==8.2.1 — 1 advisory(ies): CVE-2026-30827 (express-rate-limit: IPv4-mapped IPv6 addresses bypass per-client rate limiting o)

High
Category
Supply Chain
Confidence
90% confidence
Finding
express-rate-limit 8.2.1 is reported as vulnerable to bypass via IPv4-mapped IPv6 addresses, which can defeat per-client rate limiting. In an MCP server context this matters because rate limiting is often relied on to protect expensive operations, auth flows, and abuse-prone endpoints from repeated requests.

Known Vulnerable Dependency: fast-uri==3.1.0 — 7 advisory(ies): CVE-2026-13676 (fast-uri vulnerable to host confusion via failed IDN canonicalization); CVE-2026-18446 (fast-uri vulnerable to host confusion via backslash authority introducer); CVE-2026-75975 (fast-uri vulnerable to server-side request forgery via malformed IPv6 normalizat) +4 more

High
Category
Supply Chain
Confidence
80% confidence
Finding
fast-uri 3.1.0 is flagged for host confusion and SSRF-related parsing issues. As a transitive dependency of schema/validation tooling, the lockfile presence alone does not prove a reachable exploit path, but if any URI parsing or trust decisions rely on this library indirectly, malformed attacker-supplied URLs could bypass validation assumptions.

Known Vulnerable Dependency: hono==4.11.9 — 16 advisory(ies): CVE-2026-56762 (Hono missing validation of cookie name on write path in setCookie()); CVE-2026-47676 (Hono: app.mount() strips mount prefix using undecoded path, causing incorrect ro); CVE-2026-47675 (Hono: Cookie helper does not sanitize sameSite and priority, allowing Set-Cookie) +13 more

High
Category
Supply Chain
Confidence
88% confidence
Finding
hono 4.11.9 carries multiple advisories affecting routing, cookies, and request handling. Since the MCP SDK depends on Hono for HTTP serving, these flaws can be relevant to a network-exposed backend where route confusion, cookie mishandling, or authorization bypass may affect agent-facing or operator-facing endpoints.

Known Vulnerable Dependency: ip-address==10.0.1 — 2 advisory(ies): CVE-2026-69192 (ip-address: Address4 decodes leading-zero octets as decimal while resolvers deco); CVE-2026-42338 (ip-address has XSS in Address6 HTML-emitting methods)

High
Category
Supply Chain
Confidence
80% confidence
Finding
ip-address 10.0.1 is flagged for address parsing ambiguity and XSS in HTML-emitting methods. The rate-limiting stack depends on this package, so the parsing flaw may matter if IP normalization is used in security decisions; however, the XSS portion is only relevant if HTML-emitting helpers are actually used, which is not shown here.

Known Vulnerable Dependency: path-to-regexp==8.3.0 — 2 advisory(ies): CVE-2026-4923 (path-to-regexp vulnerable to Regular Expression Denial of Service via multiple w); CVE-2026-4926 (path-to-regexp vulnerable to Denial of Service via sequential optional groups)

High
Category
Supply Chain
Confidence
84% confidence
Finding
path-to-regexp 8.3.0 is flagged for ReDoS/DoS conditions involving crafted route patterns or matching behavior. Because it underpins routing in the server stack, an attacker may be able to trigger excessive CPU consumption if affected route processing is reachable with maliciously shaped paths.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill instructs users to install and run a bundled MCP server that performs outbound network access to Teller APIs and can consume environment variables, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates a trust gap: agents or operators may execute the skill without clear least-privilege boundaries, increasing the risk of unintended network use, environment exposure, or broader capability abuse if the packaged server is modified or compromised.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The documentation describes an endpoint that generates approval and borrow transaction calldata and says to use the results directly for sequential submission, but it does not warn that these are live on-chain actions that can move funds, grant token allowances, and create debt positions. In an agent skill context, that omission increases the chance an automated system or user will treat the output as routine data rather than high-risk transaction instructions.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The repayment endpoint is documented as generating approval and repay transactions without clearly stating that the output is intended for live blockchain submission and may approve token spending. In an MCP/agent setting, this can mislead integrators into auto-submitting the returned transactions, exposing users to unintended approvals, incorrect repayment amounts, or execution on the wrong chain.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README advertises wallet-specific data retrieval and generation of encoded borrow/repay transactions, but it does not warn users that wallet addresses may be sensitive financial metadata or that generated transactions can move funds and create debt if blindly submitted. In an agent-integrated MCP context, this omission increases the chance that operators or downstream agents treat the tool output as inherently safe and execute high-risk on-chain actions without adequate review.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The client allows its base URL to be overridden via environment variable or constructor option, and then sends wallet addresses and loan-related parameters to that endpoint. In an agent or MCP deployment, a compromised environment, malicious operator, or unsafe configuration could silently redirect sensitive financial metadata and transaction requests to an attacker-controlled service, enabling surveillance, tampering, or deceptive transaction generation.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This code sends wallet addresses, collateral details, loan amounts, and bid identifiers to remote API endpoints via query parameters. There is no confirmation prompt, user-facing log, or inline documentation in this file warning that sensitive financial/account data will be transmitted off-system.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill exposes tools that prepare encoded borrow and repayment transactions, which are financially impactful blockchain actions, but the tool descriptions and responses do not clearly warn that the outputs are transaction payloads that can move funds, create debt, approve token spending, or repay loans. In an agent setting, this increases the chance that downstream systems or users treat the results as routine data rather than sensitive action material, raising the risk of accidental signing or unsafe automation.

Known Vulnerable Dependency: body-parser==2.2.2 — 1 advisory(ies): CVE-2026-12590 (body-parser vulnerable to denial of service when invalid limit value silently di)

Low
Category
Supply Chain
Confidence
78% confidence
Finding
body-parser 2.2.2 is flagged for a denial-of-service condition related to invalid limit handling. This is a real issue at the dependency level, though its practical severity in this skill is limited because exploitation depends on the server exposing affected parsing paths to attacker-controlled requests.

Known Vulnerable Dependency: esbuild==0.27.3 — 1 advisory(ies): GHSA-g7r4-m6w7-qqqr (esbuild allows arbitrary file read when running the development server on Window)

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

Known Vulnerable Dependency: qs==6.15.0 — 3 advisory(ies): CVE-2026-82417 (qs: Denial of Service via Attacker Controlled isBuffer); CVE-2026-8723 (qs has a remotely triggerable DoS: qs.stringify crashes with TypeError on null/u); CVE-2026-82562 (qs array-limit bypass via bracket-key comma parsing)

Low
Category
Supply Chain
Confidence
80% confidence
Finding
qs 6.15.0 has reported denial-of-service issues in querystring parsing/stringifying edge cases. In this context it is a real but comparatively low-severity risk because exploitation depends on exposed Express query/body parsing with attacker-controlled inputs, and the likely outcome is resource exhaustion rather than data compromise.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"author": "",
  "license": "MIT",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.26.0",
    "zod": "^4.3.6"
  },
  "devDependencies": {
Confidence
92% confidence
Finding
The dependency uses a caret range, which allows newer semver-compatible versions to be installed over time rather than a single exact reviewed version. In an MCP server that may be installed and run by agents, this increases supply-chain risk because a compromised or breaking upstream release could be pulled in without an explicit code change in this repository.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"license": "MIT",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.26.0",
    "zod": "^4.3.6"
  },
  "devDependencies": {
    "@types/node": "^25.2.3",
Confidence
92% confidence
Finding
The zod package is referenced with a caret version, so builds may resolve to different upstream releases over time. While common in JavaScript projects, this still creates a real but low-severity supply-chain exposure if a malicious or flawed release is published and later installed by users or automation.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"zod": "^4.3.6"
  },
  "devDependencies": {
    "@types/node": "^25.2.3",
    "tsx": "^4.21.0",
    "typescript": "^5.9.3"
  }
Confidence
84% confidence
Finding
The development dependency @types/node is also unpinned, allowing variation between installs. This is less dangerous than a runtime dependency, but it can still affect build integrity and reproducibility and may contribute to supply-chain risk in CI or developer environments.

Unpinned Dependencies

Low
Category
Supply Chain
Content
},
  "devDependencies": {
    "@types/node": "^25.2.3",
    "tsx": "^4.21.0",
    "typescript": "^5.9.3"
  }
}
Confidence
88% confidence
Finding
The tsx devDependency is unpinned and is directly used to start and develop the server, which means a newly resolved version could execute different code in local or CI environments. Because tsx is an executable tool, compromise of the package or an unsafe update path would have supply-chain implications, though primarily during development/build time.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"devDependencies": {
    "@types/node": "^25.2.3",
    "tsx": "^4.21.0",
    "typescript": "^5.9.3"
  }
}
Confidence
84% confidence
Finding
TypeScript is specified with a caret range, so compiler behavior and installed artifacts may change across environments and over time. This is mainly a build reproducibility and supply-chain hygiene issue rather than an immediately exploitable flaw, but it still weakens control over what code and tooling are executed.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/tellermcp-server/src/client.ts:15