Back to skill

Security audit

AI通识课资深专家V8.1AIPC

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches an AI teaching assistant, but its privacy promises are stronger than its cloud-upload behavior and implemented PII controls.

Install only if you are comfortable with a teaching workflow that may send minimized or derived metadata to configured cloud providers. Treat the zero-upload claim as meaning raw materials are intended to stay local, not that no data ever leaves the machine. Review EDGE_CLOUD_ENDPOINT, API-key handling, model/ffmpeg downloads, and any deployment guide steps before use with student or classroom data.

Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (254)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if script_args is None:
        script_args = []
    cmd = [str(venv_python), str(SCRIPT_DIR / script_name), *script_args]
    return subprocess.run(
        cmd,
        check=False,
        capture_output=capture_output,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
)
        if not os.path.exists(ps_script):
            return None
        result = subprocess.run(
            ["powershell", "-NoProfile", "-ExecutionPolicy", "Bypass",
             "-File", ps_script, "--probe-only"],
            capture_output=True, text=True, timeout=15,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Content
):
        if hasattr(cost_monitor, attr):
            try:
                return bool(getattr(cost_monitor, attr))
            except Exception:
                return False
    # 3) 鍏滃簳锛歝umulative_cost_usd >= monthly_budget_usd
Confidence
50% confidence
Finding
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Content
for attr in ("cumulative_cost_usd", "cumulative_cost", "total_cost_usd", "cost_usd"):
        if hasattr(cost_monitor, attr):
            try:
                return float(getattr(cost_monitor, attr))
            except Exception:
                continue
    return 0.0
Confidence
50% confidence
Finding
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Content
for attr in ("monthly_budget_usd", "monthly_budget", "budget_usd", "budget"):
        if hasattr(cost_monitor, attr):
            try:
                v = float(getattr(cost_monitor, attr))
                return v
            except Exception:
                continue
Confidence
50% confidence
Finding
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"""运行 exe 并尝试给定参数,返回是否成功(用于校验下载是否完整)。"""
    for flag in flags:
        try:
            result = subprocess.run(
                [str(exe_path), flag],
                capture_output=True,
                timeout=15,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
VENV_DIR.parent.mkdir(parents=True, exist_ok=True)
    log.info(f"[venv] 创建统一虚拟环境:{VENV_DIR}")
    subprocess.run([sys.executable, "-m", "venv", str(VENV_DIR)], check=True)
    if not VENV_PYTHON.exists():
        raise RuntimeError(f"虚拟环境创建后未找到 Python:{VENV_PYTHON}")
    log.info(f"[venv] ✓ 虚拟环境已就绪:{VENV_PYTHON}")
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
raise FileNotFoundError(f"requirements.txt 不存在:{REQUIREMENTS_FILE}")

    log.info(f"[venv] 安装依赖:{REQUIREMENTS_FILE}")
    subprocess.run([str(venv_python), "-m", "pip", "install", "--upgrade", "pip"], check=True)
    subprocess.run(
        [str(venv_python), "-m", "pip", "install", "-r", str(REQUIREMENTS_FILE)],
        check=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
log.info(f"[venv] 安装依赖:{REQUIREMENTS_FILE}")
    subprocess.run([str(venv_python), "-m", "pip", "install", "--upgrade", "pip"], check=True)
    subprocess.run(
        [str(venv_python), "-m", "pip", "install", "-r", str(REQUIREMENTS_FILE)],
        check=True,
    )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if not VENV_PYTHON.exists():
        return
    cmd = [str(VENV_PYTHON), str(script_path), *sys.argv[1:]]
    raise SystemExit(subprocess.call(cmd))


def runtime_summary() -> dict[str, str]:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Content
if not hasattr(self, attr):
            return []
        errors: List[Exception] = []
        for fn in getattr(self, attr):
            try:
                fn({"target": None, **payload})
            except Exception as e:
Confidence
50% confidence
Finding
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Content
def add_global(self, event: str, fn) -> None:
        attr = f"_global_{event}"
        if hasattr(self, attr):
            getattr(self, attr).append(fn)

    def trigger_global(self, event: str, **payload) -> List[Exception]:
        attr = f"_global_{event}"
Confidence
50% confidence
Finding
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Tainted flow: 'req' from sys.stdin.read (line 857, user input) → urllib.request.urlopen (network output)

Medium
Category
Data Flow
Content
req = urllib.request.Request(url, data=payload, headers=headers, method="POST")

    try:
        with urllib.request.urlopen(req, timeout=connect_timeout) as resp:
            body = resp.read().decode("utf-8")
            provider_resp = json.loads(body)
    except socket.timeout as exc:
Confidence
65% confidence
Finding
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

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

Critical
Category
Data Flow
Content
req = urllib.request.Request(url, data=payload, headers=headers, method="POST")

    try:
        with urllib.request.urlopen(req, timeout=connect_timeout) as resp:
            body = resp.read().decode("utf-8")
            provider_resp = json.loads(body)
    except socket.timeout as exc:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Intent-Code Divergence

Low
Confidence
88% confidence
Finding
The file header says it installs the environment for "ai-literacy-expert-v7.3", while the provided manifest is for "ai-literacy-expert-v8.1.0-aipc". This is an active documentation/code-context contradiction that can mislead operators about which skill the script belongs to or is intended to prepare.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest strongly frames this skill around AI-PC edge/cloud teaching with 'local inference' and especially 'zero-upload privacy'. In contrast, the documented fallback chain explicitly escalates OCR/ASR/TTS/RAG requests from local providers to named cloud providers, which changes the data-handling model in a way not reflected by the privacy-focused description.

Intent-Code Divergence

Medium
Confidence
82% confidence
Finding
The compatibility note says the older file remains 'completely valid' for V7 inheritance. However, the inherited guidance includes cloud fallback paths that are at odds with the newer manifest's zero-upload privacy intent, so the version note overstates compatibility and creates a documentation-to-intent contradiction.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The file documents the skill's core philosophy and engineering implementation around video decoding, frame extraction, multimodal understanding, VLM deployment, and NPU scheduling. That emphasis materially diverges from the manifest's stated primary role as an AI literacy teaching expert, lesson-planning assistant, and p5.js teaching-widget gatekeeper, suggesting the documented behavior/scope is broader and different than the declared educational workflow focus.

Description-Behavior Mismatch

Low
Confidence
80% confidence
Finding
The manifest frames the skill as a teaching expert, courseware assistant, and curriculum-design helper for AI literacy scenarios. The audit report additionally claims use for '教育部门:区域教学质量监控', which is a broader monitoring/oversight function not clearly reflected in the manifest description and may represent a different operational intent.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The report states 'V7 原始数据永远本地' and frames the model as moving from cloud-capable to zero upload, but elsewhere it explicitly describes edge-cloud protocol interactions, standardized requests, callback structures, audit records for each interaction, and metadata-level cloud exchange. While not necessarily unsafe, the wording 'zero upload' is contradicted by the documented presence of cloud-bound request data, making the documentation materially misleading about what is actually transmitted.

Intent-Code Divergence

Medium
Confidence
92% confidence
Finding
The document explicitly states that V7 requires no public inbound access, yet later deployment examples configure externally reachable listeners and load-balanced exposure. In particular, the Nginx default server proxies `/api/` on port 80 and the Kubernetes service uses `type: LoadBalancer`, which contradicts the earlier 'no public inbound' claim rather than merely omitting nuance.

Intent-Code Divergence

Medium
Confidence
88% confidence
Finding
The security section states original data is kept on-device for 7 days with automatic encrypted deletion, but the backup script archives the RAG database, audit logs, and full config daily and only deletes backups after 30 days. That creates a direct contradiction between stated retention behavior and documented operational behavior.

Context-Inappropriate Capability

Low
Confidence
75% confidence
Finding
The manifest describes an AI literacy teaching expert and course-preparation workflow, but this file also instructs creation of systemd services, Nginx reverse proxies, SSL issuance, firewall rules, Docker/Kubernetes deployment, and bootable offline ISO construction. Those are infrastructure-management capabilities not obviously justified by the educational-assistant purpose itself.

Description-Behavior Mismatch

Medium
Confidence
86% confidence
Finding
Lines L040-L041 claim a strict zero-upload/privacy guarantee for original data, reinforced elsewhere as '100% 隐私'. However, the workflow at L113-L115 sends a '课堂摘要 + 标签' to the cloud after processing raw classroom audio, which is a behaviorally weaker guarantee than the absolute privacy framing in the description. This is a semantic mismatch between the claimed privacy boundary and the actual described data flow.

Static analysis

Detected: suspicious.destructive_delete_command, suspicious.dynamic_code_execution, suspicious.exposed_secret_literal

Documentation contains a destructive delete command without an explicit confirmation gate.

Warn
Code
suspicious.destructive_delete_command
Location
references/deployment-guide.md:1619

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
support/p5.min.js:1

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
support/p5.sound.min.js:2

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/deployment-guide.md:592