T09 · Insecure Skill Coding Practices
- Location
index.ts:14- Finding
Unrestricted MCP Server URL Permits Plaintext Credential Transmission and Untrusted Tool Registration
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Otto Travel plugin is coherent for travel booking, but it gives a remote, configurable MCP server authenticated booking and account-management authority without enough endpoint validation or user-facing controls.
Review this before installing. Use only the default Otto HTTPS endpoint unless you fully trust a custom MCP server, because that server receives OAuth material and travel details. Treat the token file as sensitive, and require explicit confirmation in your workflow before any flight, hotel, preference, or loyalty-program change.
index.ts:14Unrestricted MCP Server URL Permits Plaintext Credential Transmission and Untrusted Tool Registration
fast-uri 3.1.0 has multiple advisories involving URI parsing ambiguities, host confusion, and possible SSRF edge cases. In a travel-booking integration that likely processes remote endpoints, redirects, or externally supplied URLs through SDK validation layers, URI misparsing can have significant security consequences if any trust decisions depend on parsed hosts.
hono 4.12.9 is flagged by many advisories covering routing, cookie, and path handling issues. Because the MCP SDK depends on Hono for server behavior, flaws in request routing or header/cookie handling could affect exposed tool endpoints and make the plugin's network surface more dangerous than a purely local library would be.
ip-address 10.1.0 includes advisories for address parsing discrepancies and an XSS issue in HTML-emitting methods. In this dependency chain it comes from express-rate-limit, so the main realistic concern is incorrect IP interpretation affecting security decisions such as rate limiting or network allow/deny logic if such functionality is enabled.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
}
/**
* Get a valid access token. Loads from disk, refreshes if expired,
* or runs the full device auth flow if no tokens exist.
*/
async getAccessToken(): Promise<string> {
The README explicitly states that OAuth access/refresh tokens are stored locally in a predictable path, but it does not warn that these credentials are sensitive or advise users to protect file permissions. If another local user, malware, or backup/sync process can read that file, the tokens could be reused to access the user's Otto account and perform travel-related actions.
The skill exposes MCP and network-backed capabilities but does not declare any explicit tool scope, permissions, or allowed-tools boundaries. In a booking plugin, this weakens least-privilege controls and makes it easier for an agent to invoke sensitive actions such as reservations or account operations without clear policy constraints or user understanding.
The skill advertises flight and hotel booking but does not warn that these tools may create real reservations, spend loyalty points, or incur financial charges. In this context, omission is dangerous because users and agents may treat tool use as informational when it can trigger irreversible real-world transactions.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"properties": {
"serverUrl": {
"type": "string",
"description": "Otto MCP server URL (e.g. https://api.ottotheagent.com/mcp). Defaults to production."
}
}
}
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"properties": {
"serverUrl": {
"type": "string",
"description": "Otto MCP server URL (e.g. https://api.ottotheagent.com/mcp). Defaults to production."
}
}
}
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"properties": {
"serverUrl": {
"type": "string",
"description": "Otto MCP server URL (e.g. https://api.ottotheagent.com/mcp). Defaults to production."
}
}
}
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"properties": {
"serverUrl": {
"type": "string",
"description": "Otto MCP server URL (e.g. https://api.ottotheagent.com/mcp). Defaults to production."
}
}
}
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"properties": {
"serverUrl": {
"type": "string",
"description": "Otto MCP server URL (e.g. https://api.ottotheagent.com/mcp). Defaults to production."
}
}
}
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"properties": {
"serverUrl": {
"type": "string",
"description": "Otto MCP server URL (e.g. https://api.ottotheagent.com/mcp). Defaults to production."
}
}
}
This code retrieves an access token and injects it into the Authorization header for every MCP request. While the top comment documents the behavior for developers, there is no user-facing disclosure, confirmation, or visible warning that credentials will be sent to a remote server.
The lockfile pins @hono/node-server 1.19.11, which is reported to include path handling flaws such as repeated-slash middleware bypass and Windows serve-static path traversal. Even though this skill is a travel plugin and not obviously a file-serving app, the vulnerable package is present in the shipped dependency graph and could become exploitable if the SDK exposes affected server features.
body-parser 2.2.2 is flagged for a denial-of-service condition around invalid limit handling. As a transitive dependency of Express in the MCP SDK, it may be reachable if the skill accepts HTTP request bodies through the embedded server stack, making resource exhaustion plausible though likely limited.
qs 6.15.0 is associated with multiple denial-of-service and parsing-bypass issues. Since qs is commonly used to parse query strings and request bodies in Express stacks, malformed attacker-controlled parameters could trigger excessive work or bypass intended array limits on exposed HTTP endpoints.
The production dependency uses a caret range, which permits automatic installation of newer minor and patch releases. While common in JavaScript projects, this increases supply-chain risk because a compromised or breaking upstream release could be pulled in without explicit review, and this skill depends on an MCP SDK that may influence external tool interactions.
"extensions": ["./index.ts"]
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.25.0"
},
"devDependencies": {
"@types/node": "^22.0.0",
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
"@modelcontextprotocol/sdk": "^1.25.0"
},
"devDependencies": {
"@types/node": "^22.0.0",
"typescript": "^5.7.0"
},
"engines": {
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
},
"devDependencies": {
"@types/node": "^22.0.0",
"typescript": "^5.7.0"
},
"engines": {
"node": ">=18.0.0"