Back to skill

Security audit

课件帮 Aippt

Security checks for vulnerabilities and agentic risk

Overview

This PPT skill is mostly coherent, but it handles paid API calls and account tokens in ways users should review carefully before installing.

Install only if you are comfortable sending presentation topics, outlines, requirements, and optional research material to Kejian365 and potentially spending account balance when a task is created. Do not paste the auth token into chat; prefer a scoped environment secret, rotate the token if exposed, and remove task_state.json or params.json files that contain credentials after use.

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/create_ppt_task.py:76
Finding

Billed PPT Task Creation Lacks an Enforced Transaction Confirmation Gate

Content
View full analysis

Vulnerability Details

File Location: scripts/create_ppt_task.py:76-80, 108-124
Vulnerability Type: Unconfirmed billed operation
Risk Level: Medium

Technical Analysis

The task-creation API deducts billing when a PPT task is created, as documented in api-reference.md:55-61. However, the executable entry point does not require a confirmation flag, approval artifact, dry-run step, or transaction-specific authorization before sending the billed request.

The relevant code is:

python
def api_create(params, token):
    for required in ("topic", "themeId", "outline"):
        if not params.get(required):
            return None, f"缺少必填参数: {required}", {}
    client = SkillHttpClient(auth_token=token, timeout=60)
    body = {k: params[k] for k in ("topic", "themeId", "outline")}
    for k in ("requirements", "material", "themeConfig", "illustrationMode", "generateType"):
        if k in params: body[k] = params[k]
    raw = client.post(f"{BASE_URL}/aippt/v1/skill/task/create", body)
    if not (raw.get("data") or {}).get("created"):
        return None, raw.get("rspDesc", "任务创建失败"), raw
    return (raw["data"] or {}).get("ppt_id", ""), "", raw
python
# ── A: Create or retry ────────────────────────────────────────────────────
if state is None or state.get("status") == "CREATE_FAILED":
    if not params:
        print("ERROR: 缺少任务参数", flush=True); sys.exit(1)
    _log(wd, f"创建任务: {params.get('topic')!r}")
    try:
        ppt_id, err, raw = api_create(params, token)
    except SkillHttpError as e:
        save_state(wd, {"status": "CREATE_FAILED", "error": str(e)})
        print("FAILED: 网络请求失败", flush=True)
        print(f"错误:   {e}", flush=True); sys.exit(1)

SKILL.md directs the conversational workflow to display the outline and wait for user confirmation, but this requirement is not enforced by the script. A caller only needs valid parameters, a valid account token, and a work directory whose state is absent or marked `CREAT ...[truncated 1890 chars]

Remediation
View remediation

Remediation Suggestions

  1. Require an explicit confirmation parameter before any billed request, such as --confirm-charge, and reject task creation when it is absent.
  2. Bind confirmation to the exact transaction details, including a hash of the outline, theme, page count, account identity, and displayed cost estimate. Reject stale or mismatched approvals.
  3. Add a dry-run mode that validates parameters and displays the expected billing details without invoking the task-creation API.
  4. Distinguish network retry from billing retry. Do not automatically retry a potentially submitted request unless the service supports a caller-supplied idempotency key and the same key is reused.
  5. Record only a non-secret approval receipt in the work directory so polling can proceed without repeating confirmation or retaining unnecessary credential material.
  6. Keep the conversational confirmation in SKILL.md, but treat it as user-interface guidance rather than a security control; enforce the authorization requirement inside the executable path.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (18)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The README explicitly instructs users to paste an auth token into chat and says the AI will remember it for the session. This creates a real risk of credential exposure through chat logs, model memory within the session, transcript retention, debugging systems, or accidental reuse by the agent in later turns.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This code chunk does not implement the declared presentation-generation functionality. It is only a low-level networking utility for sending authenticated JSON HTTP requests and handling errors. While such a client could be a supporting component inside a PPT-generation skill, the supplied chunk by itself does not perform any of the core behaviors described in the declaration, such as creating slide outlines, selecting themes, generating slide content, or designing layouts. Therefore, the actual behavior shown is materially different from the declared primary purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description claims an end-to-end PPT creation skill, but the provided code chunk has a much narrower function: it calls the 课件帮 themes endpoint and outputs available themes. While theme selection is one component mentioned in the description, this code does not generate presentations, create outlines, produce slide content, or design layouts. Therefore the declared purpose materially overstates the actual behavior of this code chunk.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The activation criteria are extremely broad and can trigger on common requests like 'make me a PPT' or 'create slides,' increasing the chance the skill runs when the user did not intend to send their content to this third-party service. Overbroad triggering is dangerous here because the skill collects topic requirements and forwards presentation content to an external platform using stored credentials.

Content

No source excerpt is available for this finding.

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

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

md
| Missing / `CREATE_FAILED` | Calls create API (or retries) |
| `PENDING` / `RUNNING` | Polls only, never creates again |
| `DONE` | Returns success immediately |
| `GENERATION_FAILED` | Returns failure; delete state file to retry |

---

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README is entirely written as if the skill is to be used in Chinese and instructs the user to invoke it with Chinese phrasing, without offering any language choice or stating that the skill is intentionally limited to Chinese users. This can violate language/locale policy when a skill mandates a specific language without opt-in or justification.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The invocation guidance tells users to '直接对 AI 说' followed by a generic request like '帮我做一个关于 ... 的 PPT'. This is broad natural language that could easily overlap with ordinary conversation, and the README does not define stricter trigger conditions, scope limits, or negative examples to prevent unintended activation.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

Telling users to paste an account secret directly into chat normalizes unsafe secret handling and exposes the token to any system that stores, reviews, summarizes, or processes the conversation. In agent contexts this is especially dangerous because the credential may be accessible to tool traces, operators, logs, or prompt-injection side effects during the same session.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill instructs the agent to use environment secrets, read/write files, and make networked API calls, but it does not declare any corresponding tool scope or permissions boundary. This creates a transparency and least-privilege problem: the skill can exfiltrate user content and use credentials without an explicit capability declaration for review or enforcement.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill does not prominently disclose that user-provided presentation content, requirements, and optionally generated research material will be transmitted to a third-party platform. This creates a privacy and data-handling risk because users may share confidential business, academic, or training content without informed consent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Defaulting output language to Chinese without explicit user choice can cause unintended transmission and transformation of content in a language the user did not request. While not a severe exploit by itself, it can lead to policy, usability, and confidentiality issues if content is mistranslated or routed through a localization path the user did not intend.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The document says authentication is transparently injected from KEJIAN365_AUTH_TOKEN and handled automatically, but it does not warn that user content and requests are being sent to an external third-party service under stored credentials. In an agent workflow, hidden credential use plus silent outbound transmission increases the risk of users unknowingly sending sensitive presentation material to an external provider.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The API reference explicitly states that billing is deducted when POST /aippt/v1/skill/task/create is called, but it does not require the skill to obtain explicit user confirmation immediately before making that charge-triggering request. In an agent setting, this can cause unintended purchases or abusive prompting to spend a user's balance without clear consent, especially because task creation and billing occur in a single call.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script saves the authentication token into task_state.json so it persists across polling runs. Storing bearer credentials on disk unnecessarily increases exposure to local file disclosure, accidental inclusion in logs/backups, or reuse by other processes/users, and the token persistence is broader than needed for simple PPT task tracking.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill silently writes the user's authentication token to local disk without notifying the user, which creates a credential-handling transparency and security problem. Users may reasonably expect a PPT-generation tool to use a token transiently, not to retain it in a workspace file that could be read later by other users, tools, or backup systems.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The exception messages use Chinese text such as "失败", "网络错误", and "请求超时" directly in code. This forces a specific locale for user-visible output and violates the policy against language-specific behavior without offering user choice or documenting a justified locale constraint.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/create_ppt_task.py (reported line 12)May include surrounding context.

python
def _utf8_stdio():
    for a in ("stdout", "stderr"):
        s = getattr(sys, a)
        if hasattr(s, "reconfigure"):
            s.reconfigure(encoding="utf-8", errors="replace")
        elif hasattr(s, "buffer"):

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/list_themes.py (reported line 9)May include surrounding context.

python
def _utf8_stdio():
    for a in ("stdout", "stderr"):
        s = getattr(sys, a)
        if hasattr(s, "reconfigure"):
            s.reconfigure(encoding="utf-8", errors="replace")
        elif hasattr(s, "buffer"):

Static analysis

No suspicious patterns detected.