Back to skill

Security audit

清华校园技能包

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its campus-services purpose, but it needs Review because email actions can execute without the documented confirmation and the package handles sensitive credentials and sessions.

Install only if you are comfortable giving this skill local access to campus login, mailbox/API credentials, browser sessions, and campus booking/email authority. Before using mail, treat send and mark-read as immediately executable script actions, not just previews, and avoid storing/syncing the runtime vault or master key where others can read them.

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
campus/mail/scripts/mail.py:169
Finding

Email Mutations Lack Executable Confirmation Enforcement

Content
View full analysis

Vulnerability Details

File Location: campus/mail/scripts/mail.py, lines 169–207 and 236–241
Vulnerability Type: Missing authorization gate for externally visible and state-changing email operations
Risk Level: Medium

Complete Code Snippet

python
def cmd_send(from_name, to, subject, body, cc=""):
    accounts = _load_accounts()
    acc = _find_account(accounts, from_name)
    try:
        msg = MIMEText(body, "plain", "utf-8")
        msg["From"] = formataddr([acc.get("from_name", acc["user"]), acc["user"]], charset="utf-8")
        msg["To"] = to
        if cc:
            msg["Cc"] = cc
        msg["Subject"] = Header(subject, "utf-8")
        to_list = [to] + ([cc] if cc else [])
        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())
        server.quit()
        common.output_json({"status": "ok", "type": "send", "from": acc["user"], "to": to,
                            "subject": subject, "message": "发送成功"})
    except Exception as e:
        common.output_json({"status": "error", "message": f"发送失败: {str(e)[:100]}"})
        sys.exit(1)


def cmd_mark_read(account_name, uid):
    accounts = _load_accounts()
    acc = _find_account(accounts, account_name)
    try:
        imap = _connect_imap(acc)
    except Exception as e:
        common.output_json({"status": "error", "message": f"IMAP 连接失败: {str(e)[:100]}"})
        sys.exit(1)
    try:
        imap.select("INBOX")
        if uid:
            imap.store(uid.encode(), "+FLAGS", "\\Seen")
        else:
            typ, data = imap.search(None, "UNSEEN")
           
...[truncated 3354 chars]
Remediation
View remediation

Remediation Suggestions

  1. Add an explicit --confirm flag to the argument parser and pass it into every state-changing command.
  2. Reject send and mark-read unless confirmation is present.
  3. Without confirmation, return a structured dry-run preview containing:
    • Selected account
    • Exact To and Cc recipients
    • Subject and complete body
    • For mark-read, the exact UIDs and number of messages that would be changed
  4. Require the confirmed execution to match the preview. Prefer generating a short-lived, integrity-protected confirmation token bound to the operation parameters so changed recipients or content require a new confirmation.
  5. Treat bulk mark-read as a separate high-impact action and require explicit bulk confirmation rather than interpreting an omitted UID as automatic approval for all unread messages.
  6. Enforce authorization in executable code rather than relying solely on campus/mail/SKILL.md.
  7. Add regression tests asserting that SMTP sendmail() and IMAP store() are never reached without valid confirmation.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • 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 (255)

Tainted flow: 'req' from os.environ.get (line 252, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · campus/madmodel/scripts/madmodel.py (reported line 256)May include surrounding context.

python
headers={"Content-Type": "application/json",
                                          "Authorization": f"Bearer {tok}",
                                          "Cookie": f"wengine_vpn_ticket={ticket}"})
    with urllib.request.urlopen(req, timeout=timeout) as r:
        return r.read().decode("utf-8", "replace")

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill description emphasizes end-user campus services, but the content also includes credential vault management, master-key handling, credential reset/remove/verify operations, and status exposure. Hiding or underemphasizing security-sensitive credential-management capabilities makes the skill more dangerous because users may not realize it can manipulate stored secrets and decryption configuration.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill description emphasizes end-user campus services, but the content also includes credential vault management, master-key handling, credential reset/remove/verify operations, and status exposure. Hiding or underemphasizing security-sensitive credential-management capabilities makes the skill more dangerous because users may not realize it can manipulate stored secrets and decryption configuration.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill description emphasizes end-user campus services, but the content also includes credential vault management, master-key handling, credential reset/remove/verify operations, and status exposure. Hiding or underemphasizing security-sensitive credential-management capabilities makes the skill more dangerous because users may not realize it can manipulate stored secrets and decryption configuration.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill description emphasizes end-user campus services, but the content also includes credential vault management, master-key handling, credential reset/remove/verify operations, and status exposure. Hiding or underemphasizing security-sensitive credential-management capabilities makes the skill more dangerous because users may not realize it can manipulate stored secrets and decryption configuration.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill description emphasizes end-user campus services, but the content also includes credential vault management, master-key handling, credential reset/remove/verify operations, and status exposure. Hiding or underemphasizing security-sensitive credential-management capabilities makes the skill more dangerous because users may not realize it can manipulate stored secrets and decryption configuration.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill description emphasizes end-user campus services, but the content also includes credential vault management, master-key handling, credential reset/remove/verify operations, and status exposure. Hiding or underemphasizing security-sensitive credential-management capabilities makes the skill more dangerous because users may not realize it can manipulate stored secrets and decryption configuration.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill description emphasizes end-user campus services, but the content also includes credential vault management, master-key handling, credential reset/remove/verify operations, and status exposure. Hiding or underemphasizing security-sensitive credential-management capabilities makes the skill more dangerous because users may not realize it can manipulate stored secrets and decryption configuration.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill description emphasizes end-user campus services, but the content also includes credential vault management, master-key handling, credential reset/remove/verify operations, and status exposure. Hiding or underemphasizing security-sensitive credential-management capabilities makes the skill more dangerous because users may not realize it can manipulate stored secrets and decryption configuration.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill description emphasizes end-user campus services, but the content also includes credential vault management, master-key handling, credential reset/remove/verify operations, and status exposure. Hiding or underemphasizing security-sensitive credential-management capabilities makes the skill more dangerous because users may not realize it can manipulate stored secrets and decryption configuration.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The documentation explicitly describes a credential vault protected by a single transferable master key and even exposes a key show operation for extracting that key. In a skill that handles campus SSO, literature API access, and optional LLM/API secrets, making the decryption key exportable and allowing fallback storage in the skill directory materially increases the chance that compromise of one host, terminal session, logs, or synced files yields all stored credentials.

Content

Scanner excerpt · campus/CREDS.md (reported line 46)May include surrounding context.

md
- 解密只需**一个主密钥**,来源优先级:① 环境变量 `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`

## 铁律

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · campus/amap/SKILL.md (reported line 153)May include surrounding context.

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

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · campus/amap/scripts/amap.py (reported line 5)May include surrounding context.

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

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · campus/amap/scripts/amap.py (reported line 52)May include surrounding context.

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

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · campus/amap/scripts/amap.py (reported line 54)May include surrounding context.

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

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · campus/amap/scripts/amap.py (reported line 59)May include surrounding context.

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

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · campus/literature/scripts/literature.py (reported line 10)May include surrounding context.

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

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · campus/literature/scripts/literature.py (reported line 59)May include surrounding context.

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

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · campus/literature/scripts/literature.py (reported line 503)May include surrounding context.

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

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · campus/mail/scripts/mail.py (reported line 34)May include surrounding context.

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

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · campus/mail/scripts/mail.py (reported line 36)May include surrounding context.

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

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · campus/mail/scripts/mail.py (reported line 60)May include surrounding context.

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

CLI(子命令均输出纯 JSON):
  amap.py text        --keywords <词>      [--city 北京市] [--type 050000] [--offset 20]

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · campus/base-cas/scripts/login.py (reported line 835)May include surrounding context.

python
"""creds.py — 技能包统一凭据管理

单一加密保险箱(skill/campus/runtime/credentials.enc),所有子 SKILL 共用。
凭据整体加密,解密只需一个主密钥(环境变量 CAMPUS_MASTER_KEY / OS keyring / 密钥文件)。

每条凭据有元数据(用途/获取方式/影响范围/是否已配),支持查询与责任告知。

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · campus/base-cas/scripts/login.py (reported line 841)May include surrounding context.

python
"""creds.py — 技能包统一凭据管理

单一加密保险箱(skill/campus/runtime/credentials.enc),所有子 SKILL 共用。
凭据整体加密,解密只需一个主密钥(环境变量 CAMPUS_MASTER_KEY / OS keyring / 密钥文件)。

每条凭据有元数据(用途/获取方式/影响范围/是否已配),支持查询与责任告知。

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · campus/base-cas/scripts/login.py (reported line 859)May include surrounding context.

python
"""creds.py — 技能包统一凭据管理

单一加密保险箱(skill/campus/runtime/credentials.enc),所有子 SKILL 共用。
凭据整体加密,解密只需一个主密钥(环境变量 CAMPUS_MASTER_KEY / OS keyring / 密钥文件)。

每条凭据有元数据(用途/获取方式/影响范围/是否已配),支持查询与责任告知。