Back to skill

Security audit

超星智雅 MCP 一键接入

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Chaoxing/StudyAI MCP connector, but it persists OAuth secrets, rewrites MCP configuration, and can run refresh behavior automatically, so users should review it carefully before installing.

Install only if you are comfortable storing Chaoxing OAuth client credentials and tokens on this machine and allowing the skill to update WorkBuddy MCP configuration. Prefer environment variables over --save when possible, protect ~/.workbuddy, review any scheduled task or daemon usage, and revoke or rotate Chaoxing credentials if the machine or files may be exposed.

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

Warning
Location
scripts/chaoxing-mcp-auto.mjs:256
Finding
Missing OAuth State Validation Enables Login CSRF and Account Substitution## Vulnerability Details **File Location**: `scripts/chaoxing-mcp-auto.mjs:256, 294-305, 593-610`; `scripts/chaoxing-mcp-lab.mjs:84, 438-460` **Vulnerability Type**: OAuth login CSRF / authorization response injection **Risk Level**: Medium ### Technical Analysis Both OAuth implementations generate predictable `state` values derived from the requested scope rather than cryptographically random, transaction-specific values: ```javascript // scripts/chaoxing-mcp-auto.mjs:250-258 function buildAuthUrl(cred, scope) { const u = new URL(AUTHORIZE_URL); u.searchParams.set('client_id', cred.clientId); u.searchParams.set('response_type', 'code'); u.searchParams.set('redirect_uri', REDIRECT_URI); if (scope !== null && scope !== undefined) u.searchParams.set('scope', scope); u.searchParams.set('state', 'auto-' + (scope ?? '')); return u.toString(); } ``` The callback handler accepts any supplied authorization code without retrieving or validating the returned `state`: ```javascript // scripts/chaoxing-mcp-auto.mjs:294-305 if (u.pathname === '/callback') { const code = u.searchParams.get('code'); const err = u.searchParams.get('error'); const desc = u.searchParams.get('error_description'); if (!code) { log(`授权失败:${err} / ${desc}`); res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); return res.end(page(`<h1 class="fail">✘ 授权未通过:${esc(err || '')} ${esc(desc || '')}</h1><p><a href="/lab">← 返回重试(检查 scope 取值)</a></p>`)); } log('收到授权码,正在换取令牌…'); const { status, json } = await exchangeCode(cred, code); ``` The setup callback has the same weakness and applies the resulting tokens to local state and WorkBuddy configuration: ```javascript // scripts/chaoxing-mcp-auto.mjs:593-610 if (u.pathname === '/callback') { const code = u.searchParams.get('code'); const err = u.searchParams.get('error'); const desc = u.searchParams.get('error_description'); const cred = pendingCred || (await getCreds()); if (!cred) { r ...[truncated 3805 chars]
Remediation
## Remediation Suggestions 1. Generate a new state value for each authorization attempt using a cryptographically secure source such as `crypto.randomBytes(32).toString('base64url')`. 2. Store the expected state only in process memory together with its creation time and intended authorization parameters. 3. Require an exact state match before exchanging an authorization code. 4. Reject callbacks with missing, unknown, expired, or previously consumed state values. 5. Consume the state before or atomically with code exchange to prevent callback replay. 6. Do not encode scope or other predictable values as the security state. Store such metadata alongside the random state in local process memory. 7. Close the callback server after the first valid authorization transaction. 8. Use Authorization Code with PKCE if the provider supports it, while retaining state validation for CSRF protection. 9. Apply the same correction to `runAuthLab`, `runSetup`, and `chaoxing-mcp-lab.mjs` so no alternative entry point remains vulnerable.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (37)

MCP Config Access

High
Category
Agent Snooping
Content
slug: chaoxing-mcp-oauth
title: 超星智雅 MCP 一键接入
displayName: 超星智雅 MCP 一键接入
summary: 三步接入超星智雅(StudyAI)MCP:本机回调授权换 JWT、自动写入 mcp.json、refresh_token 常驻保活,附 7 类故障速查表。
description: 指导用户将超星智雅/StudyAI MCP 服务接入 WorkBuddy 的完整流程:引导用户提供 OAuth2 凭据、本机起回调服务完成授权码换 JWT、写入 mcp.json、配置 refresh_token 常驻保活,并处理 grant_version_stale / scope_denied / invalid_scope 等故障。适用于用户要求连接超星智雅 MCP、令牌过期修复、或重新授权的场景。
version: 1.3.0
tags: ["chaoxing", "mcp", "oauth", "studyai", "education"]
Confidence
95% confidence
Finding
The skill explicitly instructs writing static Authorization headers to mcp.json and maintaining refresh tokens for persistent access. Access to MCP connector configuration is security-sensitive because compromise, accidental disclosure, or overbroad automation can expose bearer tokens and silently redirect future agent traffic under attacker-controlled credentials.

MCP Config Access

High
Category
Agent Snooping
Content
title: 超星智雅 MCP 一键接入
displayName: 超星智雅 MCP 一键接入
summary: 三步接入超星智雅(StudyAI)MCP:本机回调授权换 JWT、自动写入 mcp.json、refresh_token 常驻保活,附 7 类故障速查表。
description: 指导用户将超星智雅/StudyAI MCP 服务接入 WorkBuddy 的完整流程:引导用户提供 OAuth2 凭据、本机起回调服务完成授权码换 JWT、写入 mcp.json、配置 refresh_token 常驻保活,并处理 grant_version_stale / scope_denied / invalid_scope 等故障。适用于用户要求连接超星智雅 MCP、令牌过期修复、或重新授权的场景。
version: 1.3.0
tags: ["chaoxing", "mcp", "oauth", "studyai", "education"]
license: MIT
Confidence
95% confidence
Finding
The description advertises automatic mcp.json writes and refresh-token persistence as core functionality. Because MCP config controls how the agent authenticates to external services, automated edits without strong guardrails can persist sensitive tokens and alter trusted integrations in a way that survives the current session.

MCP Config Access

High
Category
Agent Snooping
Content
# 超星智雅 / StudyAI MCP 接入

帮助用户把超星智雅(StudyAI)的 MCP 服务接入 WorkBuddy。平台不提供 OAuth 发现文档,WorkBuddy 内置 OAuth 流程不可用,因此必须**本机起回调服务、人工授权换 JWT、以静态 Bearer 头写入 mcp.json、再用 refresh_token 常驻保活**。本技能自带三个脚本(`scripts/` 目录),**日常使用只需一键命令**。

## ⚡ 一键式自动接入(v1.1,推荐日常使用)
Confidence
96% confidence
Finding
The skill's main workflow depends on launching a localhost callback, obtaining JWTs, writing a static Bearer token into mcp.json, and using refresh tokens for ongoing access. That creates a durable authentication foothold inside agent configuration; if mishandled, it can lead to unauthorized service access or token leakage beyond the original setup operation.

Ae1

High
Category
analysis-evasion
Content
核心脚本:`scripts/chaoxing-mcp-auto.mjs`。一条命令自动完成:检查令牌 → 未过期直接验证 → 过期自动刷新 → 刷新失败自动弹授权页 → 写 mcp.json → 验证 → 自动关闭授权服务。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Credential Access

High
Category
Privilege Escalation
Content
**官方文档确认的边界**(https://sharewh2.xuexi365.com/share/1ee530c1-4542-444e-8ef8-5f56247a26fa):授权必须用户人工点一次「确认授权」(无 client_credentials/免确认模式),这是平台安全红线——一键自动化的极限即 v1.1 现状:授权环节仅保留一次人工点击,其余全自动。另注意:智雅平台「重置密钥/停止授权」会立即冻结数据通道(表现为令牌未过期却 403),遇到时让用户去智雅「第三方授权管理」检查授权状态是否「启用中」。

凭据优先级:环境变量 `CX_CLIENT_ID`/`CX_CLIENT_SECRET` > `~/.workbuddy/chaoxing-credentials.json`(`--save` 写入)。
授权成功后脚本会记住成功的 scope 写回凭据文件,下次授权免输入。
Agent 使用守则:**会话里遇到 MCP 401/403,或用户要求连接超星 MCP 时,直接跑一键命令**(Windows 下 node 用 WorkBuddy 托管路径 `~/.workbuddy/binaries/node/versions/<ver>/node.exe`,凭据文件已存在则无需问用户)。只有一键命令走到「自动授权」分支时才需要用户在浏览器点一次「确认授权」。
Confidence
96% confidence
Finding
The skill instructs storing OAuth client credentials in a local JSON file under the user's home directory and encourages automatic reuse. Local plaintext credential persistence materially increases the blast radius of host compromise, accidental sharing, backup leakage, or access by other local software, especially because the same file can enable reauthorization and token minting.

Credential Access

High
Category
Privilege Escalation
Content
**安全红线(必须遵守)**:
- 绝不把用户的 client_id / client_secret / 令牌 / 账号信息写入本技能任何文件、对话输出或日志
- 凭据通过**环境变量**或 `--save` 存入 `~/.workbuddy/chaoxing-credentials.json`(本机专用),泄露时在智雅「密钥管理 → 重置密钥」作废重来

## 平台关键事实(实测结论,勿重复探测)
Confidence
92% confidence
Finding
Although the skill includes a 'do not log secrets' warning, it still prescribes saving credentials to a local file via --save. That contradiction leaves the user protected from chat/log exposure but still exposed to local plaintext secret theft, making this a real credential-handling weakness rather than a false positive.

Credential Access

High
Category
Privilege Escalation
Content
*   node chaoxing-mcp-auto.mjs --daemon           # 常驻保活(临期自动刷新,进程不退出)
 *   node chaoxing-mcp-auto.mjs --daemon-once      # 无人值守单次保活(Windows 计划任务用:只刷新不弹授权页,静默退出)
 *
 * 凭据优先级:环境变量 CX_CLIENT_ID / CX_CLIENT_SECRET > chaoxing-credentials.json
 * 安全说明:--save 会把凭据明文存到 ~/.workbuddy/chaoxing-credentials.json(仅本机使用),
 *          泄露时去智雅「密钥管理 → 重置密钥」作废,再 --save 新密钥即可。
 */
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
*   node chaoxing-mcp-auto.mjs --daemon           # 常驻保活(临期自动刷新,进程不退出)
 *   node chaoxing-mcp-auto.mjs --daemon-once      # 无人值守单次保活(Windows 计划任务用:只刷新不弹授权页,静默退出)
 *
 * 凭据优先级:环境变量 CX_CLIENT_ID / CX_CLIENT_SECRET > chaoxing-credentials.json
 * 安全说明:--save 会把凭据明文存到 ~/.workbuddy/chaoxing-credentials.json(仅本机使用),
 *          泄露时去智雅「密钥管理 → 重置密钥」作废,再 --save 新密钥即可。
 */
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
*   node chaoxing-mcp-auto.mjs --daemon           # 常驻保活(临期自动刷新,进程不退出)
 *   node chaoxing-mcp-auto.mjs --daemon-once      # 无人值守单次保活(Windows 计划任务用:只刷新不弹授权页,静默退出)
 *
 * 凭据优先级:环境变量 CX_CLIENT_ID / CX_CLIENT_SECRET > chaoxing-credentials.json
 * 安全说明:--save 会把凭据明文存到 ~/.workbuddy/chaoxing-credentials.json(仅本机使用),
 *          泄露时去智雅「密钥管理 → 重置密钥」作废,再 --save 新密钥即可。
 */
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

MCP Config Access

High
Category
Agent Snooping
Content
fs.writeFileSync(STATE_FILE, JSON.stringify(s, null, 2) + '\n', 'utf8');
}

/** 把 access_token 写入 mcp.json;refresh_token 存本地状态文件(避免敏感信息进 mcp.json) */
function writeMcpConfig(accessToken) {
  let cfg = { mcpServers: {} };
  try {
Confidence
90% confidence
Finding
Although this duplicate finding reflects the same code path, the underlying issue remains that the script programmatically updates MCP configuration tied to persistent OAuth credentials. In a skill specifically designed to connect an MCP service, this behavior is contextually expected, but the lack of hardening around secret-bearing config files makes it security-relevant.

MCP Config Access

High
Category
Agent Snooping
Content
fs.writeFileSync(STATE_FILE, JSON.stringify(s, null, 2) + '\n', 'utf8');
}

/** 把 access_token 写入 mcp.json;refresh_token 存本地状态文件(避免敏感信息进 mcp.json) */
function writeMcpConfig(accessToken) {
  let cfg = { mcpServers: {} };
  try {
Confidence
90% confidence
Finding
Although this duplicate finding reflects the same code path, the underlying issue remains that the script programmatically updates MCP configuration tied to persistent OAuth credentials. In a skill specifically designed to connect an MCP service, this behavior is contextually expected, but the lack of hardening around secret-bearing config files makes it security-relevant.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill instructs the agent to use environment variables, local credential files, localhost callback services, and outbound network access, but it declares no explicit tool scope or permissions. That mismatch can cause the platform or user to underestimate what the skill can do, increasing the chance of silent secret handling and configuration changes without informed approval.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The activation guidance is broad enough to trigger not only on explicit setup requests but also on generic MCP 401/403 errors, causing the agent to run OAuth reauthorization or token-refresh workflows automatically. In a skill that handles secrets and rewrites mcp.json, overbroad invocation increases the risk of unnecessary credential access and unintended config mutation.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill directs storage of OAuth credentials, refresh tokens, and Bearer tokens in local files and mcp.json, while also modifying connector configuration, but the warning is not prominent at the point where the workflow is introduced. Users may proceed without appreciating that long-lived secrets will be persisted locally and reused automatically.

External Transmission

Medium
Category
Data Exfiltration
Content
"mcpServers": {
    "chaoxing-studyai": {
      "type": "http",
      "url": "https://api.chaoxing.com/openai/studyai/data",
      "headers": { "Authorization": "Bearer <JWT>" },
      "description": "超星智雅 StudyAI(OAuth2 授权码 + 静态 Bearer)"
    }
Confidence
74% confidence
Finding
This example shows a static Bearer token placed directly into mcp.json headers. Unlike the earlier endpoint references, this line normalizes persistent transmission of a reusable secret in configuration, which becomes dangerous if the file is readable by other processes, users, backups, or sync systems.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script writes OAuth client credentials and access/refresh tokens to predictable local files in plaintext under ~/.workbuddy. Those secrets can be recovered by other local users, malware, backups, or support tooling, and the token is also copied into mcp.json as a static Bearer header, increasing exposure surface.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
Accepting the client secret as a positional command-line argument exposes it to shell history, process listings, audit logs, and job schedulers. This is especially risky for a setup utility intended for regular users, who may paste secrets directly into a terminal without realizing the retention risk.

Description-Behavior Mismatch

Medium
Confidence
87% confidence
Finding
The manifest describes guiding a user through connecting the Chaoxing MCP service, handling authorization, writing mcp.json, and refresh-token maintenance. This file additionally implements an experimental scope-probing workflow with predefined candidate scopes and a free-form scope test interface, which is broader than straightforward connection guidance and actively explores provider authorization behavior.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The script invokes platform subprocesses to open the browser and later spawns a detached background refresh process automatically. These side effects exceed passive guidance, can persist beyond the user's immediate session, and occur without an explicit just-in-time consent gate, increasing the risk of unexpected local execution behavior.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script silently modifies ~/.workbuddy/mcp.json to install a bearer token-backed MCP server entry. Changing a user's active client configuration without explicit confirmation can redirect future requests, create persistent trust in a static token, and make rollback difficult if the configuration is incorrect or later abused.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The script writes the access token and refresh token to a predictable file under the user's home directory. Persisting long-lived OAuth credentials on disk without strong protections or an explicit warning materially increases the chance of credential theft by other local processes, users, backups, or accidental disclosure.

External Transmission

Medium
Category
Data Exfiltration
Content
const CFG = {
  clientId: process.env.CX_CLIENT_ID || argOf('client-id'),
  clientSecret: process.env.CX_CLIENT_SECRET || argOf('client-secret'),
  tokenUrl: 'https://api.chaoxing.com/auth/oauth2/token',
  mcpUrl: 'https://api.chaoxing.com/openai/studyai/data',
  serverName: 'chaoxing-studyai',
};
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
const CFG = {
  clientId: process.env.CX_CLIENT_ID || argOf('client-id'),
  clientSecret: process.env.CX_CLIENT_SECRET || argOf('client-secret'),
  tokenUrl: 'https://api.chaoxing.com/auth/oauth2/token',
  mcpUrl: 'https://api.chaoxing.com/openai/studyai/data',
  serverName: 'chaoxing-studyai',
};
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
const CFG = {
  clientId: process.env.CX_CLIENT_ID || argOf('client-id'),
  clientSecret: process.env.CX_CLIENT_SECRET || argOf('client-secret'),
  tokenUrl: 'https://api.chaoxing.com/auth/oauth2/token',
  mcpUrl: 'https://api.chaoxing.com/openai/studyai/data',
  serverName: 'chaoxing-studyai',
};
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
const CFG = {
  clientId: process.env.CX_CLIENT_ID || argOf('client-id'),
  clientSecret: process.env.CX_CLIENT_SECRET || argOf('client-secret'),
  tokenUrl: 'https://api.chaoxing.com/auth/oauth2/token',
  mcpUrl: 'https://api.chaoxing.com/openai/studyai/data',
  serverName: 'chaoxing-studyai',
};
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.potential_exfiltration

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/chaoxing-mcp-auto.mjs:228

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/chaoxing-mcp-lab.mjs:194

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/chaoxing-mcp-auto.mjs:42

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/chaoxing-mcp-lab.mjs:38

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/chaoxing-mcp-refresh.mjs:28

Sensitive-looking file read is paired with a network send.

Warn
Code
suspicious.potential_exfiltration
Location
scripts/chaoxing-mcp-auto.mjs:94