Back to skill

Security audit

清华网络学堂

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly aligned with Tsinghua Learn automation, but it stores login/session data and can change account state with several under-scoped safety controls.

Only install this if you trust the publisher and are comfortable giving it your Tsinghua Learn login. Before use, disable automatic mark-read unless you really want unread notices/files changed during todo checks, avoid any plaintext temporary credential file workflow, and treat the local credentials, browser profile, and session files as sensitive account access material.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (6)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_config.py:40
Finding

Silent plaintext-equivalent fallback when DPAPI encryption fails

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:256
Finding

Predictable temporary file is prescribed for plaintext credentials

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/learn_api.py:88
Finding

Authentication cookies are broadly scoped and marked non-secure

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/install_deps.py:10
Finding

Automatic Python dependency installation lacks artifact integrity verification

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/install_playwright.py:15
Finding

Browser installation redirects executable downloads to an unverified third-party mirror

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/todos_api.py:136
Finding

Read-only todo queries silently mark all announcements and course files as read

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (58)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

声明描述的是面向清华网络学堂的业务自动化能力,核心行为应包括登录学堂、查看待办、下载课件、提交作业等。实际代码并未访问网络学堂、处理账户密码、执行任何学习任务操作,而只是安装 Playwright Chromium 依赖。这不是声明中的主要功能,而是一个独立的环境安装脚本。虽然可视为支持性实现细节,但该片段本身的直接用途与声明的技能功能明显不同,且访问的外部资源是 Playwright 镜像而不是学堂站点,因此应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是一个面向清华网络学堂的网站自动化工具,核心能力应围绕网络访问、身份认证、课程/作业操作等。而实际代码仅实现了本地图片转 PDF 的文件处理功能,没有任何网络请求、浏览器自动化、学堂接口调用、凭据处理或与网络学堂相关的逻辑。其主要目的、操作对象和资源访问范围都与声明明显不符,因此属于高度明确的描述与行为不匹配。

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

The skill intentionally stores credentials, browser profile cookies, and session tokens locally. Even with DPAPI, the combination of reusable cookies, JSESSIONID, and CSRF tokens creates a high-value credential cache; compromise of the local user context, profile directory, or skill workspace could enable account takeover or session hijacking.

Content

Scanner excerpt · SKILL.md (reported line 121)May include surrounding context.

md
| 数据 | 位置 | 说明 |
|------|------|------|
| 登录凭据 | `credentials.json` | Windows DPAPI 加密(绑定当前用户账户,仅 Windows 支持) |
| 浏览器登录状态 | `profiles/learn_profile/` | Chrome Profile 含 cookies,避免每次触发 2FA |
| Session 令牌 | `sessions/learn_session.json` | JSESSIONID + CSRF Token |

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 · AGENTS.md (reported line 45)May include surrounding context.

md
_SKILL_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

_CRED_FILE   = os.path.join(_SKILL_DIR, "credentials.json")
_CONFIG_FILE = os.path.join(_SKILL_DIR, "config.json")
_STATE_FILE  = os.path.join(_SKILL_DIR, "sessions", "learn_session.json")
_FP_FILE     = os.path.join(_SKILL_DIR, "profiles", "learn_fingerprint.json")

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 · SKILL.md (reported line 601)May include surrounding context.

md
_SKILL_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

_CRED_FILE   = os.path.join(_SKILL_DIR, "credentials.json")
_CONFIG_FILE = os.path.join(_SKILL_DIR, "config.json")
_STATE_FILE  = os.path.join(_SKILL_DIR, "sessions", "learn_session.json")
_FP_FILE     = os.path.join(_SKILL_DIR, "profiles", "learn_fingerprint.json")

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 · scripts/_config.py (reported line 12)May include surrounding context.

python
_SKILL_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

_CRED_FILE   = os.path.join(_SKILL_DIR, "credentials.json")
_CONFIG_FILE = os.path.join(_SKILL_DIR, "config.json")
_STATE_FILE  = os.path.join(_SKILL_DIR, "sessions", "learn_session.json")
_FP_FILE     = os.path.join(_SKILL_DIR, "profiles", "learn_fingerprint.json")

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 · scripts/_config.py (reported line 117)May include surrounding context.

python
_SKILL_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

_CRED_FILE   = os.path.join(_SKILL_DIR, "credentials.json")
_CONFIG_FILE = os.path.join(_SKILL_DIR, "config.json")
_STATE_FILE  = os.path.join(_SKILL_DIR, "sessions", "learn_session.json")
_FP_FILE     = os.path.join(_SKILL_DIR, "profiles", "learn_fingerprint.json")

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

This function persists the user's portal username and password to a local credentials.json file, and the docstring confirms that on non-Windows systems it falls back to base64 encoding. In the context of a skill that automates login to a real university system, local compromise, backup leakage, or accidental file exposure can directly reveal working credentials.

Content

Scanner excerpt · scripts/_config.py (reported line 132)May include surrounding context.

python
return {k: decode_cred(v) for k, v in cred.items()}

def save_credentials(username, password, student_id="", name=""):
    """Windows DPAPI 加密后写入 credentials.json(非 Windows 回退 base64 编码)"""
    data = {
        "username": encode_cred(username),
        "password": encode_cred(password),

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/install_playwright.py (reported line 20)May include surrounding context.

python
def run():
    print("正在安装 Playwright Chromium...")
    env = os.environ.copy()
    env["PLAYWRIGHT_DOWNLOAD_HOST"] = _MIRROR
    result = subprocess.run(
        [sys.executable, "-m", "playwright", "install", "chromium"],

Credential Access

High
Category
Privilege Escalation
Confidence
89% confidence
Finding

Referencing credentials.json for centralized username/password loading indicates direct handling of stored credentials. In this skill context, which automates access to a real university account, local credential files are especially sensitive because compromise enables unauthorized login and downstream access to coursework and personal data.

Content

Scanner excerpt · scripts/login_auto.py (reported line 17)May include surrounding context.

python
【核心原则】
  固定 profile 路径:profiles/learn_profile/
  账号密码从 credentials.json 统一读取(禁止硬编码)
"""
import sys, os, json, time, re
sys.stdout.reconfigure(encoding='utf-8')

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The credential-loading path imports a helper specifically intended to retrieve stored credentials for automated login. This confirms the code is designed to access reusable secrets, which is dangerous if the helper reads from insecure local storage or if the host is compromised, because the attacker gets durable account access.

Content

Scanner excerpt · scripts/login_auto.py (reported line 24)May include surrounding context.

python
from playwright.sync_api import sync_playwright
import requests

# ====== 账号密码(从 credentials.json 统一加载)=======
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from _config import load_credentials, get_state_file, get_fp_file, get_profile_dir

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The CLI can perform actual local cleanup via --cleanup, which may delete files from the workspace despite the skill being described as Learn-platform automation. This scope expansion is dangerous because an agent or user may run the command without realizing it has destructive local side effects unrelated to the platform task.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file describes --reset as '清空所有数据' and elsewhere exposes cleanup actions, but it does not provide any caution, confirmation note, or warning about the impact on user data or local state. For markdown files, omission of warnings around behaviors that can affect user data or system integrity is in scope.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · CHANGELOG.md (reported line 58)May include surrounding context.

md
- 修改铁律 5 措辞(密码仅在初始化时收集)

## v1.0.3 (2026-05-02)
- 全面启用 TLS 验证:去掉 `learn_api.py`、`login_manager.py` 等 6 个脚本的 `verify=False`
- 新增 `--cred-stdin`:凭据通过 stdin JSON 传入,避免密码上命令行
- `install_deps.py` 依赖 pin 最低版本号
- SKILL.md 新增铁律 6(提交确认)+ "数据与安全"章节

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
97% confidence
Finding

The skill declares capabilities to read environment variables, access the filesystem, use the network, and execute shell commands, but does not constrain them with an explicit tool scope. In a skill that handles passwords, cookies, session tokens, downloads, and file operations, missing least-privilege boundaries increases the blast radius if the skill logic is abused or extended beyond its stated purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest says credentials are stored locally with DPAPI, but also requires a password environment variable and separately documents interactive initialization. That inconsistency can lead to secrets being exposed through environment inheritance, process inspection, logs, or agent/runtime configuration, especially because this skill already handles highly sensitive login material.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Using vague affirmations such as '好' as a trigger for cleanup is unsafe because such phrases commonly appear in normal conversation and may be misinterpreted as authorization for destructive file deletion. In a skill that can remove cached files automatically, this raises the risk of unintended data loss or action confusion.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The instruction to handle unspecified requests '尽力帮你完成' lacks clear trigger boundaries, which is risky in a skill with shell, file, and network capabilities. Broad natural-language delegation can cause the agent to perform sensitive actions outside the intended workflow, including arbitrary file operations or unreviewed interactions with external resources.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation says non-Windows handling should error, but the implementation instead falls back to base64 or returns the original value on failure. Base64 is not encryption, so on non-Windows systems credentials are effectively stored in reversible form, creating a real confidentiality risk for the username/password this skill explicitly collects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

This code writes usernames, passwords, student IDs, and names to credentials.json, which is a safety-relevant file write involving sensitive data. While the docstring mentions DPAPI/base64 behavior, there is no user-facing warning, confirmation, or logging that credentials are being persisted locally, and the non-Windows fallback is especially important to disclose because it is only encoding, not strong protection.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module docstring states the behavior in Chinese, and the script's user-facing messages throughout are hardcoded in Chinese. This creates a natural-language locale constraint with no option for the user to select another language, which matches the policy-violation category for language/locale forcing.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/install_deps.py (reported line 44)May include surrounding context.

python
def install(package):
    r = subprocess.run(
        [sys.executable, "-m", "pip", "install", package],
        capture_output=True, timeout=120
    )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/install_playwright.py (reported line 22)May include surrounding context.

python
print("正在安装 Playwright Chromium...")
    env = os.environ.copy()
    env["PLAYWRIGHT_DOWNLOAD_HOST"] = _MIRROR
    result = subprocess.run(
        [sys.executable, "-m", "playwright", "install", "chromium"],
        capture_output=False, env=env
    )

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function submits a local file and optional text content directly to the homework endpoint once called, with no built-in confirmation, preview, destination validation, or user-warning in this code path. In an automation skill that handles sensitive coursework and authenticated sessions, this raises the risk of accidental or manipulated submission of the wrong file/content under the user's identity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This code file performs safety-relevant actions: it loads username/password from credentials storage, logs into a remote service, and saves session state to disk. While the docstring describes the workflow, it does not clearly warn the user that sensitive credentials and reusable session tokens are being accessed and persisted locally.

Content

No source excerpt is available for this finding.