T09 · Insecure Skill Coding Practices
- Location
src/mcp-config.json:24- Finding
Hardcoded GitHub Personal Access Token in Tracked Configuration
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This MCP client has a coherent purpose, but it ships unsafe defaults and credential-handling issues that could let connected tools act without the user control the documentation promises.
Review carefully before installing. Do not use the packaged GitHub token; revoke it if you control it. Pin MCP server package versions, remove wildcard auto-approval, require approvals to fail closed, avoid passing the full environment to child MCP servers, and treat all connected MCP servers as privileged programs that can read files or act with configured account credentials.
src/mcp-config.json:24Hardcoded GitHub Personal Access Token in Tracked Configuration
src/secure-client.js:211Approval Controls Warn but Do Not Prevent Unapproved Tool and Resource Execution
src/client.js:75All Parent-Process Environment Variables Are Exposed to Spawned MCP Servers
src/mcp-config.json:5Runtime Execution of Unversioned Packages Through npx
src/client.js:83Arbitrary SSE Destinations Permit Internal-Network Requests and Insecure HTTP Transport
src/mcp-skill.js:182Sensitive-Path Protection Is Not Applied to Filesystem Tool Calls
src/client.js:190Tool Arguments and Resource Contents Are Exposed Through Logging and Events
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
// 首次调用需要批准
await client.callTool('filesystem', 'read_file', { path: './secret.txt' });
// ⚠️ 警告:工具调用需要批准
// 批准后无需重复确认
This example shows persistent approval of the read_file tool followed by direct access to secret.txt, effectively demonstrating how sensitive file reads can proceed without repeated user confirmation. In an MCP client connected to local filesystem servers, broad durable approval materially increases the chance of credential or secret exfiltration if the client or server is misused.
// 批准后无需重复确认 client.approveTool('filesystem', 'read_file'); await client.callTool('filesystem', 'read_file', { path: './secret.txt' }); // ✅ 工具已批准,直接执行
Referenced artifact was not completely inspected
import { OpenClawMCPSkill } from './src/mcp-skill.js';
Referenced artifact was not completely inspected
import { MCPClient, MCPServerConfig, MCPClientConfig } from './src/client.js';
Referenced artifact was not completely inspected
import { SecureMCPClient } from './src/secure-client.js';
fast-uri 3.1.0 has multiple URI parsing and canonicalization advisories, including host confusion and possible SSRF-relevant edge cases. Since it is used by ajv in the dependency tree, exploitation depends on whether untrusted schemas, URIs, or references are processed, but the underlying dependency issue is real and potentially serious in systems that validate attacker-supplied structured data.
hono 4.12.8 is listed with numerous advisories spanning cookie handling, routing, and path-processing behavior. Because Hono is a core web framework in the transitive stack, these issues can materially affect request handling and security boundaries if the skill uses the SDK's HTTP/server features, making this more dangerous than a rarely used utility package.
ip-address 10.1.0 carries advisories for parsing ambiguity and HTML-emitting XSS behavior. This is a real dependency concern, but impact in this skill is context-dependent: it becomes significant if user-supplied IP literals are parsed for allowlists/SSRF protection or if any HTML output from the library is rendered.
path-to-regexp 8.3.0 has reported ReDoS/DoS issues tied to complex route patterns. As a router dependency, this is a legitimate risk if request paths can trigger expensive pattern evaluation, especially in services exposed over HTTP where attackers can send repeated crafted requests.
The CLI instantiates the skill with autoApprove enabled, requireApproval disabled, and autoApprovePatterns set to '*', which effectively authorizes every tool invocation without user review. In a skill that can connect to filesystem and GitHub MCP servers, this removes the primary safeguard against destructive or sensitive actions and contradicts the apparent security model implied elsewhere in the code.
At CLI startup, approval safeguards are silently disabled with no explicit warning or consent from the user. Because the CLI exposes generic tool execution and shortcuts for filesystem and GitHub operations, users may unknowingly run a mode that permits immediate execution of sensitive actions, increasing the chance of accidental data modification, deletion, or remote side effects.
The code presents approval as a security control, but in both callTool and readResource it only emits a warning when approval is required and then still executes the operation by calling the parent method. This creates a fail-open authorization bypass: sensitive tool invocations and resource reads can proceed without any actual user confirmation despite comments and API semantics implying enforcement.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
assertTrue(canAccess);
});
test('敏感路径检测 - .env 文件', () => {
const security = new MCPSecurityController();
const isSensitive = security.isSensitivePath('/app/.env');
assertTrue(isSensitive);
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
test('敏感路径检测 - .env 文件', () => {
const security = new MCPSecurityController();
const isSensitive = security.isSensitivePath('/app/.env');
assertTrue(isSensitive);
});
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
test('敏感路径检测 - passwd', () => {
const security = new MCPSecurityController();
const isSensitive = security.isSensitivePath('/etc/passwd');
assertTrue(isSensitive);
});
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
test('敏感路径检测 - passwd', () => {
const security = new MCPSecurityController();
const isSensitive = security.isSensitivePath('/etc/passwd');
assertTrue(isSensitive);
});
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
test('敏感路径检测 - passwd', () => {
const security = new MCPSecurityController();
const isSensitive = security.isSensitivePath('/etc/passwd');
assertTrue(isSensitive);
});
The entire skill description, usage guidance, and safety notes are written in Chinese, and the document does not state that the skill is region-specific or provide an opt-in language/locale choice. Under the policy, forcing a specific language without user choice is a natural-language policy violation.
The README markets default user approval as a safety property but also documents an auto-approval mode that removes that protection. In an MCP client, approval bypass weakens the trust boundary around remote tool execution and can normalize unsafe configuration, increasing the chance of unintended file access or side-effecting actions.
The README instructs users to launch an MCP server with npx and no pinned version, which causes retrieval and execution of the latest package at runtime. In an MCP client context, that creates a supply-chain risk because a compromised upstream release or typosquatted package could immediately gain local code execution and access to files or credentials exposed through the server.
This example executes the unpinned GitHub MCP server via npx, implicitly trusting whatever package version is current at invocation time. Because such a server may handle repository data and authentication tokens, an upstream compromise could lead to credential theft or unauthorized API actions.
The PostgreSQL server example also relies on unpinned remote package execution, which is especially risky because it is paired with direct database connectivity. A malicious or compromised package could exfiltrate connection strings, query data, or modify databases when users follow the documented command.
This markdown file presents the skill description in Chinese, and the rest of the document continues in that locale without any opt-in or alternative language. The policy requires flagging language or locale constraints when the skill forces a specific language without user choice or clear justification.
The documented autoApprovePatterns setting (':read_') authorizes a broad class of read operations without user confirmation. In an MCP context, seemingly read-only tools can expose sensitive local files, repository secrets, tokens, or private remote resources, so wildcard-based automatic approval reduces an important trust boundary.
const skill = new OpenClawMCPSkill({
autoApprove: false, // 是否需要用户批准
requireApproval: true, // 强制要求批准
autoApprovePatterns: ['*:read_*'], // 自动批准模式
blockedPatterns: ['*:delete_*'] // 禁止模式
});
This example initializes the base MCP client with autoApprove: true, which can permit tool execution and resource access without human confirmation. Because this skill is specifically designed to connect to external MCP servers over stdio/SSE and invoke tools/resources/prompts, automatic approval substantially increases the risk of unauthorized file access, data exfiltration, or destructive operations if a server is malicious, misconfigured, or overly privileged.
// 基础客户端
const client = new MCPClient(new MCPClientConfig({
name: 'my-client',
autoApprove: true
}));
// 安全客户端(带审计和重试)
No suspicious patterns detected.