Back to skill

Security audit

清华校园技能包

Security checks for vulnerabilities and agentic risk

Overview

This campus assistant is mostly purpose-aligned, but it needs review because it handles real accounts, email, bookings, reusable login sessions, and local code changes with several under-scoped safeguards.

Install only if you are comfortable giving this skill access to your Tsinghua CAS account, campus data, library reservations, and optional mailbox. Review the mirror-based browser install, plaintext session and mail credential storage, browser --no-sandbox launch, and autonomous code-repair instruction before use. Prefer using a dedicated OS account or isolated environment, avoid syncing the runtime folder, and require explicit confirmation for email, homework submission, bookings, cancellations, and any code change.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (8)

T08 · Insecure Dependencies

Error
Location
campus/install/scripts/fetch_artifacts.py:28
Finding
Untrusted Browser Binaries Are Installed from a Nonstandard Mirror Without Independent Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `campus/install/scripts/fetch_artifacts.py:28-32, 57-66` **Vulnerability Type**: Supply-chain compromise through an unsafe executable download source **Risk Level**: High ### Vulnerable Code ```python PLAYWRIGHT_HOSTS = [ {"name": "tencent-campus-env", "host": "https://tool.tom-thu.cn/campus-env"}, {"name": "npmmirror", "host": "https://cdn.npmmirror.com/binaries/playwright"}, {"name": "official", "host": None}, ] ``` ```python for src in PLAYWRIGHT_HOSTS: if dry_run: results.append({"source": src["name"], "action": "would use", "host": src["host"] or "official"}) continue env = os.environ.copy() if src["host"]: env["PLAYWRIGHT_DOWNLOAD_HOST"] = src["host"] common.log(f"[fetch] 尝试浏览器源: {src['name']}") try: for b in BROWSERS: r = _run([sys.executable, "-m", "playwright", "install", b], env=env) ``` ### Technical Analysis The installation process prioritizes `https://tool.tom-thu.cn/campus-env`, a nonstandard mirror, over Playwright's official distribution service. The downloaded components include Chromium and FFmpeg binaries that are later executed locally. The repository does not independently pin expected SHA-256 hashes, verify a publisher signature, or compare downloaded artifacts against a repository-controlled manifest. Although Playwright may perform integrity checks based on metadata obtained through its distribution mechanism, that is not equivalent to a project-controlled trust anchor when an alternative download host is selected. This behavior is especially sensitive because the downloaded browser subsequently handles CAS passwords, active session cookies, OTP authentication flows, email-related data, and authenticated campus pages. ### Attack Path 1. An attacker compromises the custom mirror, its hosting account, DNS resolution, or another component in its delivery chain. 2. The attacker serves a modified browser a ...[truncated 1120 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make Playwright's official CDN the default and preferred source. 2. Remove the custom mirror unless it is operationally indispensable. 3. Maintain a repository-controlled manifest of expected hashes for every supported Playwright version, platform, and artifact. 4. Verify each downloaded artifact before installation or execution. 5. Where available, verify publisher signatures in addition to hashes. 6. Require explicit user approval before falling back to any third-party mirror. 7. Record the selected source, artifact version, expected hash, and observed hash in installation output. 8. Fail closed when integrity verification cannot be completed. 9. Install dependencies in a dedicated virtual environment instead of modifying the active interpreter environment. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
campus/literature/scripts/literature.py:40
Finding
Decrypted Scopus Credentials Are Passed to an Executable Outside the Audited Project Boundary<![CDATA[ ## Vulnerability Details **File Location**: `campus/literature/scripts/literature.py:40, 96-110` **Vulnerability Type**: Secret disclosure to an unverified external executable **Risk Level**: High ### Vulnerable Code ```python SCOPUS = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "..", "..", "agent", "literature", "scopus_client.py") ``` ```python def _run_scopus(args_list): """调用 scopus_client(--quiet 静默,无 stderr 噪音),返回 (ok, 结果列表)。""" api_key = _get_key("scopus_api_key") if not api_key: common.output_json({"status": "error", "error": "missing_cred", "message": "缺少 Scopus API Key。请让用户提供 scopus_api_key(dev.elsevier.com 申请)," "用 creds.py add scopus_api_key --value-stdin 配置。"}) sys.exit(1) env = os.environ.copy() env["SCOPUS_API_KEY"] = api_key inst = _get_key("scopus_inst_token") if inst: env["SCOPUS_INST_TOKEN"] = inst cmd = [sys.executable, SCOPUS, "--quiet"] + args_list r = subprocess.run(cmd, env=env, capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=120) ``` ### Technical Analysis The Skill decrypts `scopus_api_key` and the optional institutional token from its credential vault, places them in environment variables, and executes `agent/literature/scopus_client.py`. That file is resolved outside this project directory and was not part of the audited artifact. No canonical-path restriction, ownership check, signature validation, or content-hash verification is performed before execution. Consequently, the confidentiality of the credentials depends on unrelated local code outside the Skill's reviewed trust boundary. Environment inheritance is an appropriate way to provide a secret to a trusted child process, but it is unsafe when the child executable itself is not packaged and verified with the Skill. ### Attack Path 1. An attacker or another local component creates or ...[truncated 932 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Package the Scopus client inside this Skill and include it in the normal review and release process. 2. Prefer implementing the fixed Elsevier HTTPS requests directly in `literature.py`, eliminating the external subprocess. 3. If a subprocess remains necessary, resolve the client path canonically and require it to remain beneath the Skill root. 4. Verify the client against a repository-controlled cryptographic hash before decrypting or supplying any secret. 5. Reject symlinks and files with unexpected ownership or writable permissions. 6. Pass only the minimum secret needed for the selected operation. 7. Clear secret-bearing variables from intermediate dictionaries as soon as the child process is launched. 8. Document the exact Elsevier endpoints to which the trusted client is permitted to connect. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
campus/base-cas/scripts/session.py:21
Finding
Reusable Authentication Cookies Are Persisted in Plaintext Without Restrictive File Permissions<![CDATA[ ## Vulnerability Details **File Location**: `campus/base-cas/scripts/session.py:21-42, 64-84` **Vulnerability Type**: Plaintext storage of active authentication credentials **Risk Level**: High ### Vulnerable Code ```python def _path(system): d = common.session_dir() d.mkdir(parents=True, exist_ok=True) return os.path.join(str(d), f"{system}.json") ``` ```python def save_session(system, data): data = dict(data) data["_updated"] = time.time() with open(_path(system), "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2) ``` ```python def load_cookies(system): """取 session 里保存的完整 cookie 快照(login.py _extract_session 写入)。 浏览器即用即退后,跨进程的信任态靠这些 cookie + profile 指纹恢复。 返回 playwright 可直接 add_cookies 的列表,无则返回 []。 """ s = load_session(system) if not s: return [] ck = s.get("_cookies") or [] return [c for c in ck if c.get("name") and c.get("value")] ``` ### Technical Analysis The session JSON files contain complete cookie snapshots and other reusable authentication material, including JSESSIONID, CSRF tokens, and WebVPN tickets. They are written as plaintext using ordinary `open()` semantics. Neither the file nor its parent session directory is explicitly restricted to the current user. Effective permissions therefore depend on the process umask and platform defaults. The write is also non-atomic, which can leave truncated session state after interruption. Session cookies are bearer credentials. Any process that can read them may be able to impersonate the user without knowing the CAS password or completing 2FA. ### Attack Path 1. A local attacker, compromised process, backup utility, or unintended synchronization service gains read access to `campus/runtime/sessions/`. 2. The attacker copies a system session JSON file. 3. The attacker extracts the values under `_cookies`, `jsession`, `csrf`, or `ticket`. 4. The attacker injects those values into an HTTP clien ...[truncated 714 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Encrypt session records using a key held in the operating-system keyring. 2. Create `runtime`, `sessions`, and `pending` directories with mode `0700` on POSIX systems. 3. Create session files with mode `0600` and verify their permissions before reading. 4. Use an atomic write pattern: create a protected temporary file, flush and synchronize it, then replace the destination. 5. On Windows, apply a user-only ACL rather than relying on POSIX-style modes. 6. Persist only cookies strictly required for session restoration rather than complete browser snapshots. 7. Automatically remove expired sessions and clear all session material on logout or reset. 8. Avoid including session values in backups, synchronization tools, diagnostic bundles, or logs. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
campus/base-cas/scripts/login.py:737
Finding
SMS One-Time Passwords Are Exposed Through Process Arguments and Persistent Logs<![CDATA[ ## Vulnerability Details **File Location**: `campus/base-cas/scripts/login.py:737-748, 928` **Vulnerability Type**: Sensitive authentication value exposure through command-line and log channels **Risk Level**: Medium ### Vulnerable Code ```python def submit_code(token, code, headed=False): """阶段2:CDP 连接【同一浏览器】填验证码完成登录(不重开浏览器)。""" pending = _read_pending(token) if not pending: common.output_json({"status": "error", "message": f"pending 不存在或已过期: {token}"}) sys.exit(1) system = pending["system"] ``` ```python common.log(f"[login] 填码提交 {code[:3]}***({time.strftime('%H:%M:%S')})") _fill_code_and_submit(page, code) ``` ```python ap.add_argument("--submit-code", nargs=2, metavar=("TOKEN", "CODE"), help="阶段2:填验证码完成登录") ``` ### Technical Analysis The OTP is accepted as a command-line argument. On operating systems where process command lines are visible to other users or monitoring software, the full OTP and associated pending token can be observed while the process is active. The command may also be retained in shell history, agent execution telemetry, or orchestration logs. The implementation additionally writes the first three OTP digits to `runtime/logs/campus.log`. Partial OTP logging is unnecessary and weakens the secrecy of a short authentication value. Although OTPs are short-lived, the pending authentication window is documented as five minutes, providing a practical interception window. ### Attack Path 1. The Skill initiates CAS 2FA and creates a pending login session. 2. The user supplies the SMS code. 3. The agent runs `login.py --submit-code <token> <code>`. 4. A local process observer, shell-history reader, telemetry collector, or execution logger captures the command arguments. 5. The observer obtains the OTP and pending token before expiration. 6. The observer attempts to complete or interfere with the active authentication flow. 7. Separately, a reader of `campus.log` obtains the first three OTP digits, ...[truncated 465 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Accept the OTP through protected standard input or an inherited pipe rather than a command-line argument. 2. Keep only the opaque pending token on the command line if necessary. 3. Never log any OTP character, even in masked form. 4. Ensure agent execution frameworks redact OTP input and do not retain it in telemetry. 5. Protect pending-state files and directories with user-only permissions. 6. Delete pending state on every success, failure, timeout, and exception path. 7. Reduce the pending-session lifetime to the minimum supported by the authentication service. 8. Avoid storing the invocation in shell history. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
campus/base-cas/scripts/browser.py:229
Finding
Authenticated Chromium Sessions Run with the Browser Sandbox Disabled<![CDATA[ ## Vulnerability Details **File Location**: `campus/base-cas/scripts/browser.py:229-245` **Vulnerability Type**: Browser isolation disabled for network-controlled content **Risk Level**: High ### Vulnerable Code ```python # 一律无头模式(headless): # - AI 自动流程 / WSL 无显示器 / 全新机器(产品决策:全部 headless,不需人工浏览器) # - --headed 参数保留仅向后兼容,但忽略(恒 headless) base_flags = ["--no-first-run", "--no-default-browser-check", "--disable-gpu", "--disable-dev-shm-usage", "--no-sandbox"] if extra_args is None: # 默认保留自动化 flag(常规场景) base_flags.append("--disable-blink-features=AutomationControlled") else: base_flags = [f for f in base_flags if f != "--disable-blink-features=AutomationControlled"] base_flags += extra_args cmd = [exe, "--headless=new"] + [ f"--remote-debugging-port={port}", f"--user-data-dir={profile_path}", ] + base_flags + ["about:blank"] ``` ### Technical Analysis The `--no-sandbox` flag disables Chromium's primary process-isolation boundary. The browser processes network-controlled pages from campus services, third-party library platforms, and potentially user-selected content while holding authenticated cookies and trusted-browser state. A renderer vulnerability that would ordinarily be constrained by Chromium's sandbox has a more direct route to host-level access when the sandbox is disabled. Running headless does not provide an equivalent security boundary. The CDP code probes and connects through `127.0.0.1`, which reduces remote debugging exposure, but it does not mitigate the disabled renderer sandbox. ### Attack Path 1. A legitimate external service is compromised, or a browser-level vulnerability is triggered by malicious content returned from a visited page. 2. The content exploits a vulnerability in Chromium's renderer or another browser component. 3. Because Chromium was launched with `--no-sandbox`, the exploit does not need to defeat the normal Chromium sandbox boundary. 4. Malicious code gains acc ...[truncated 810 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--no-sandbox` from the default launch arguments. 2. Detect platforms where the Chromium sandbox cannot initialize and fail with a clear configuration error. 3. If sandbox disabling is unavoidable, run Chromium inside a hardened container, virtual machine, or dedicated unprivileged operating-system account. 4. Mount sensitive directories read-only or keep them outside the browser's accessible namespace. 5. Apply operating-system confinement such as AppArmor, SELinux, seccomp, or Windows sandboxing. 6. Keep Chromium patched and align its version with the pinned Playwright release. 7. Minimize the number of external origins visited by authenticated browser contexts. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
campus/mail/scripts/mail.py:32
Finding
Mailbox Authorization Codes Are Stored in Plaintext Configuration<![CDATA[ ## Vulnerability Details **File Location**: `campus/mail/scripts/mail.py:32-60, 89-92, 175-186` **Vulnerability Type**: Plaintext storage and use of reusable mailbox credentials **Risk Level**: High ### Vulnerable Code ```python ENV_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", ".env") def _load_accounts(): """从统一 .env 读取邮箱账户配置(MAIL_ACCOUNTS)。""" if not os.path.exists(ENV_PATH): common.output_json({"status": "error", "message": f"统一配置 {ENV_PATH} 不存在。请复制 skill/campus/.env.example 为 .env 并填写。"}) sys.exit(1) try: with open(ENV_PATH, encoding="utf-8") as f: env = f.read() # 提取 MAIL_ACCOUNTS=[...](支持 JSON 数组) start = env.find("MAIL_ACCOUNTS=") if start < 0: raise ValueError("MAIL_ACCOUNTS 未找到") arr = env[env.find("[", start):] depth = 0 end = 0 for i, ch in enumerate(arr): if ch == "[": depth += 1 elif ch == "]": depth -= 1 if depth == 0: end = i + 1 break accounts = json.loads(arr[:end]) ``` ```python def _connect_imap(acc): imap = imaplib.IMAP4_SSL(acc["imap_host"], int(acc.get("imap_port", 993)), timeout=15) imap.login(acc["user"], acc["password"]) return imap ``` ```python if acc.get("smtp_ssl", True): server = smtplib.SMTP_SSL(acc["smtp_host"], int(acc.get("smtp_port", 465)), timeout=15) else: server = smtplib.SMTP(acc["smtp_host"], int(acc.get("smtp_port", 587)), timeout=15) server.starttls() server.login(acc["user"], acc["password"]) server.sendmail(acc["user"], to_list, msg.as_string()) ``` The documented configuration explicitly embeds the authorization code: ```text MAIL_ACCOUNTS=[{"name":"tsinghua","label":"Tsinghua mailbox","imap_host":"mails.tsinghua.edu.cn","imap_port":993,"smtp_host":"mails.tsinghua.edu.cn","smtp_port":465,"smtp_ssl":true,"user":"xxx@mails.tsinghua. ...[truncated 1527 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store each mailbox authorization code in the encrypted vault or operating-system keyring. 2. Keep only non-secret account metadata—host, port, address, and label—in `.env`. 3. Reference secrets by a stable credential identifier rather than embedding them in JSON. 4. Enforce mode `0600` on `.env` for POSIX systems and a user-only ACL on Windows. 5. Validate file ownership and reject configuration files writable by untrusted users. 6. Provide a migration command that transfers existing plaintext credentials into protected storage and securely removes the old values. 7. Recommend provider-specific application passwords with the narrowest available scope. 8. Avoid including `.env` in backups, diagnostics, archives, or synchronization sets. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:111
Finding
Skill Instructions Authorize Autonomous Source Modification and Live-Account Validation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:111-114` **Vulnerability Type**: Excessive agent authorization beyond least-privilege task execution **Risk Level**: Medium ### Vulnerable Instruction ```text **Bug self-repair authorization**: When encountering a bug (script error, API change, login failure, or unavailable data), the AI may modify this Skill package itself to fix it without waiting for the user. However: - Only the failing module may be changed; tested core paths must not be modified. - After fixing it, run tests/smoke_test.py and test once with real data to confirm the result. ``` ### Technical Analysis The Skill grants the agent standing authorization to modify executable source code without obtaining user approval. It also requires validation against real account data after a repair. This expands the agent's authority from invoking reviewed functionality to rewriting that functionality and exercising it against authenticated systems. A diagnosis error, malicious page content influencing the repair process, or unsafe generated patch could alter security-sensitive behavior such as authentication, submissions, email sending, or reservation operations. The instruction does not explicitly override platform safety constraints and is not a conventional instruction-hijacking payload. The issue is excessive operational authority and failure to preserve a clear approval boundary. ### Attack Path 1. A campus endpoint changes behavior or returns content that causes a script failure. 2. The agent interprets the failure as permission to edit the affected executable module. 3. The agent generates and applies a patch without user review. 4. The patch accidentally weakens authentication handling, changes request parameters, or converts a read-only operation into a state-changing one. 5. The instruction then causes the agent to test the patch using the user's real authenticated account. 6. The live test exposes data or performs an uninte ...[truncated 714 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require explicit user approval before modifying any executable source file. 2. Present the proposed patch and affected behavior before applying it. 3. Default validation to unit tests, fixtures, recorded responses, and read-only staging operations. 4. Require separate, explicit approval before any real-account test. 5. Prohibit live validation through destructive or externally visible actions, including submissions, email sending, bookings, cancellations, and bulk read-status changes. 6. Back up the original file and provide a clear rollback mechanism. 7. Re-run security-sensitive tests after every modification. 8. Restrict modifications to a dedicated working copy rather than the installed trusted package. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
campus/literature/scripts/literature.py:170
Finding
arXiv Search Queries and Responses Use Unencrypted HTTP<![CDATA[ ## Vulnerability Details **File Location**: `campus/literature/scripts/literature.py:170-176` **Vulnerability Type**: Cleartext network transmission and response-integrity failure **Risk Level**: Medium ### Vulnerable Code ```python def arxiv_search(query, count=10, date=None): """arXiv API(Atom XML)。注意:arXiv 无 date 过滤参数(搜索结果自带 published)。""" params = {"search_query": f"all:{query}", "start": "0", "max_results": str(count)} url = "http://export.arxiv.org/api/query?" + urllib.parse.urlencode(params) body, code = _http_get(url) if code != 200: raise RuntimeError(f"arXiv HTTP {code}: {body[:200]}") ``` ### Technical Analysis The search query is included in an HTTP URL and sent without TLS. A passive network observer can read the user's literature search terms. An active network attacker can alter the Atom XML response because the transport provides neither confidentiality nor server authentication. The response is parsed and presented as literature metadata. Although the XML is parsed with Python's standard `ElementTree` and is not directly executed, manipulated titles, summaries, identifiers, or links can mislead the user or influence downstream agent reasoning. ### Attack Path 1. A user performs an arXiv search through the Skill. 2. The Skill sends the query to `http://export.arxiv.org/api/query`. 3. A network observer records the complete query string. 4. An active attacker intercepts the cleartext response and replaces or modifies the Atom XML. 5. The Skill parses the modified document as legitimate arXiv metadata. 6. The agent presents falsified publications, summaries, identifiers, or links to the user. ### Impact Assessment The vulnerability exposes literature search terms and permits modification of returned search metadata. Potential effects include: - Disclosure of private research interests or project topics. - False or manipulated academic search results. - Misleading citation metadata. - Redirection towar ...[truncated 136 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use an arXiv endpoint that supports HTTPS. 2. Reject redirects that downgrade an HTTPS request to HTTP. 3. Verify the final response URL and expected hostname. 4. Set explicit limits on response size and request timeout. 5. Treat returned titles, summaries, identifiers, and links as untrusted data. 6. If the official API cannot be accessed securely, use a trusted HTTPS proxy under an explicitly documented trust model rather than silently falling back to plaintext HTTP. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (265)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This umbrella skill includes library seat and study-room booking/cancellation using CAS-authenticated personal access, which are more sensitive than a generic information lookup. If the entrypoint description does not make these write-capable personal-account actions obvious, users may trigger account-affecting behavior with insufficient awareness.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
This umbrella skill includes library seat and study-room booking/cancellation using CAS-authenticated personal access, which are more sensitive than a generic information lookup. If the entrypoint description does not make these write-capable personal-account actions obvious, users may trigger account-affecting behavior with insufficient awareness.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
This umbrella skill includes library seat and study-room booking/cancellation using CAS-authenticated personal access, which are more sensitive than a generic information lookup. If the entrypoint description does not make these write-capable personal-account actions obvious, users may trigger account-affecting behavior with insufficient awareness.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This umbrella skill includes library seat and study-room booking/cancellation using CAS-authenticated personal access, which are more sensitive than a generic information lookup. If the entrypoint description does not make these write-capable personal-account actions obvious, users may trigger account-affecting behavior with insufficient awareness.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This umbrella skill includes library seat and study-room booking/cancellation using CAS-authenticated personal access, which are more sensitive than a generic information lookup. If the entrypoint description does not make these write-capable personal-account actions obvious, users may trigger account-affecting behavior with insufficient awareness.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This umbrella skill includes library seat and study-room booking/cancellation using CAS-authenticated personal access, which are more sensitive than a generic information lookup. If the entrypoint description does not make these write-capable personal-account actions obvious, users may trigger account-affecting behavior with insufficient awareness.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
This umbrella skill includes library seat and study-room booking/cancellation using CAS-authenticated personal access, which are more sensitive than a generic information lookup. If the entrypoint description does not make these write-capable personal-account actions obvious, users may trigger account-affecting behavior with insufficient awareness.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
This umbrella skill includes library seat and study-room booking/cancellation using CAS-authenticated personal access, which are more sensitive than a generic information lookup. If the entrypoint description does not make these write-capable personal-account actions obvious, users may trigger account-affecting behavior with insufficient awareness.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This umbrella skill includes library seat and study-room booking/cancellation using CAS-authenticated personal access, which are more sensitive than a generic information lookup. If the entrypoint description does not make these write-capable personal-account actions obvious, users may trigger account-affecting behavior with insufficient awareness.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
This umbrella skill includes library seat and study-room booking/cancellation using CAS-authenticated personal access, which are more sensitive than a generic information lookup. If the entrypoint description does not make these write-capable personal-account actions obvious, users may trigger account-affecting behavior with insufficient awareness.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
This umbrella skill includes library seat and study-room booking/cancellation using CAS-authenticated personal access, which are more sensitive than a generic information lookup. If the entrypoint description does not make these write-capable personal-account actions obvious, users may trigger account-affecting behavior with insufficient awareness.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This umbrella skill includes library seat and study-room booking/cancellation using CAS-authenticated personal access, which are more sensitive than a generic information lookup. If the entrypoint description does not make these write-capable personal-account actions obvious, users may trigger account-affecting behavior with insufficient awareness.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The file explicitly authorizes the AI to modify the skill's own code and run tests when bugs occur. Self-modification is a major escalation beyond a campus-service assistant: it can alter local code, persistence, and future behavior, and it creates a path for prompt-induced unauthorized changes under the guise of 'repair'.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
Allowing autonomous code repair and testing is unjustified for the stated purpose and materially increases attack surface. An attacker or accidental prompt could drive the agent to rewrite modules, introduce backdoors, weaken safeguards, or execute broader shell/file actions under the pretext of fixing a bug.

Credential Access

High
Category
Privilege Escalation
Content
- 解密只需**一个主密钥**,来源优先级:① 环境变量 `CAMPUS_MASTER_KEY` ② OS keyring 单条(本机绑定,自动生成)③ `campus/runtime/vault/master.key`(0600,兜底)
- 文件随 SKILL 文件夹同步即可跨机携带;新设备设同一个 `CAMPUS_MASTER_KEY` 即能解密
- 主密钥管理:`creds.py key show`(读出,用于带到其他设备)/ `creds.py key set --value-stdin`(显式设置)/ `creds.py key source`(看来源)
- 旧版 `credentials.json`(keyring:/fernet: 引用)首次读取时自动迁移为 `credentials.enc`

## 铁律
Confidence
89% confidence
Finding
The documentation describes a credential vault design where a single master key can decrypt all stored secrets, and explicitly includes commands to reveal/export that key for portability. In an LLM-integrated skill, exposing key-material management and encouraging transferable decryption keys increases the risk that an agent, prompt injection, local compromise, or log/history leakage could lead to full credential disclosure across systems.

Credential Access

High
Category
Privilege Escalation
Content
覆盖高德 v3/v4 后端 HTTP 接口:地点搜索、POI 详情、周边搜索、路径规划
(步行/驾车/公交/骑行)、地理编码/逆编码、天气、IP 定位、行政区划、距离测量、
静态地图。所有调用走统一 .env 里的 AMAP_KEY(Web 服务类型)。

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
覆盖高德 v3/v4 后端 HTTP 接口:地点搜索、POI 详情、周边搜索、路径规划
(步行/驾车/公交/骑行)、地理编码/逆编码、天气、IP 定位、行政区划、距离测量、
静态地图。所有调用走统一 .env 里的 AMAP_KEY(Web 服务类型)。

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
覆盖高德 v3/v4 后端 HTTP 接口:地点搜索、POI 详情、周边搜索、路径规划
(步行/驾车/公交/骑行)、地理编码/逆编码、天气、IP 定位、行政区划、距离测量、
静态地图。所有调用走统一 .env 里的 AMAP_KEY(Web 服务类型)。

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
覆盖高德 v3/v4 后端 HTTP 接口:地点搜索、POI 详情、周边搜索、路径规划
(步行/驾车/公交/骑行)、地理编码/逆编码、天气、IP 定位、行政区划、距离测量、
静态地图。所有调用走统一 .env 里的 AMAP_KEY(Web 服务类型)。

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
覆盖高德 v3/v4 后端 HTTP 接口:地点搜索、POI 详情、周边搜索、路径规划
(步行/驾车/公交/骑行)、地理编码/逆编码、天气、IP 定位、行政区划、距离测量、
静态地图。所有调用走统一 .env 里的 AMAP_KEY(Web 服务类型)。

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
覆盖高德 v3/v4 后端 HTTP 接口:地点搜索、POI 详情、周边搜索、路径规划
(步行/驾车/公交/骑行)、地理编码/逆编码、天气、IP 定位、行政区划、距离测量、
静态地图。所有调用走统一 .env 里的 AMAP_KEY(Web 服务类型)。

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
覆盖高德 v3/v4 后端 HTTP 接口:地点搜索、POI 详情、周边搜索、路径规划
(步行/驾车/公交/骑行)、地理编码/逆编码、天气、IP 定位、行政区划、距离测量、
静态地图。所有调用走统一 .env 里的 AMAP_KEY(Web 服务类型)。

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
覆盖高德 v3/v4 后端 HTTP 接口:地点搜索、POI 详情、周边搜索、路径规划
(步行/驾车/公交/骑行)、地理编码/逆编码、天气、IP 定位、行政区划、距离测量、
静态地图。所有调用走统一 .env 里的 AMAP_KEY(Web 服务类型)。

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
覆盖高德 v3/v4 后端 HTTP 接口:地点搜索、POI 详情、周边搜索、路径规划
(步行/驾车/公交/骑行)、地理编码/逆编码、天气、IP 定位、行政区划、距离测量、
静态地图。所有调用走统一 .env 里的 AMAP_KEY(Web 服务类型)。

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
覆盖高德 v3/v4 后端 HTTP 接口:地点搜索、POI 详情、周边搜索、路径规划
(步行/驾车/公交/骑行)、地理编码/逆编码、天气、IP 定位、行政区划、距离测量、
静态地图。所有调用走统一 .env 里的 AMAP_KEY(Web 服务类型)。

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Static analysis

No suspicious patterns detected.