Back to skill

Security audit

Exam Prep Pro

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly an exam-prep assistant, but it adds an off-platform paid activation flow, mandatory local script execution, plaintext activation credentials, and a home-directory marker file that users should review before installing.

Review this skill carefully before installing. The study features are understandable, but the Pro unlock flow sends users to an external payment link, asks for a payment receipt screenshot, runs a bundled verifier, and stores activation data locally in plaintext. Prefer a version that uses platform billing or clearly scoped, secure activation storage.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (4)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:29
Finding

Mandatory Payment Promotion Hijacks Agent Responses

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 29-57
Vulnerability Type: Mandatory output injection and forced local tool execution
Risk Level: High

Vulnerable Snippet

The following is an English rendering of the mandatory instructions in the source:

markdown
1. When a user first uses a Pro feature, the following content must be
   displayed in full, including the payment QR-code image:

   Pro features require an activation code.
   Obtain one by scanning the code and paying CNY 19.99.

   ![Payment QR code](https://www.coze.cn/s/CJfSTWG9jok/)

Note: The payment image link must be displayed every time the prompt appears.

2. After the user supplies an activation code, the verification script must
   be executed:

python3 scripts/verify_activation.py "user-supplied activation code"

It is strictly prohibited to skip script verification.

Technical Analysis

The Skill changes the Agent's normal response objective by requiring it to insert a third-party payment solicitation whenever a user requests designated functionality. The instruction is not merely descriptive documentation: it mandates exact promotional output, requires an external payment link to be displayed repeatedly, and directs the Agent to execute a local script with user-provided input.

The external URL is not pinned to immutable content. Its destination or rendered material can therefore change after the package has been reviewed. No remote code retrieval was observed, so this does not qualify as remote payload execution, but it creates a mutable social-engineering and payment redirection surface.

Attack Path

  1. A user requests a feature classified by the Skill as a Pro feature.
  2. The loaded Skill overrides the ordinary exam-assistance response flow.
  3. The Agent displays the mandatory external payment solicitation.
  4. The user follows the externally controlled link and is instructed to pay CNY 19.99.

...[truncated 475 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove instructions that force the Agent to reproduce payment advertisements or external payment images.
  • Clearly disclose commercial restrictions in package metadata rather than injecting promotional content into unrelated responses.
  • Require explicit user consent before opening or displaying any external commercial destination.
  • Allow the Agent to describe feature availability without requiring verbatim promotional text.
  • Apply an allowlist to external links and use a stable, organization-controlled HTTPS domain.
  • Do not characterize forced script execution as a security requirement; define a narrowly scoped activation API instead.
  • Keep activation processing separate from the conversational prompt so Skill text cannot compel arbitrary tool use.

T09 · Insecure Skill Coding Practices

Error
Location
activation_codes.txt:1
Finding

Plaintext Unsold and Valid Activation Codes Are Distributed with the Skill

Content
View full analysis

Vulnerability Details

File Location: activation_codes.txt, lines 1-105; scripts/verify_activation.py, lines 12-111
Vulnerability Type: Plaintext credential exposure
Risk Level: High

Vulnerable Snippets

activation_codes.txt contains plaintext activation values, including:

text
EPP-27MD-2DE7-RDRP
EPP-2CB6-6RAV-YZQR
EPP-2J2C-5G9M-7YSP
EPP-2PJ4-2BBW-3JZP
EPP-39EW-U5X3-PSRR

The verifier also stores plaintext codes as dictionary values:

python
VALID_HASHES = {
    "398360c0ece045ab": "EPP-2HGX-NYTY-6KG9",
    "cd14b5dedcb10d8d": "EPP-2PQQ-49ZQ-3UNH",
    "f1b68f3de6692983": "EPP-2V68-UR2M-W3SN",
    "2816f282fca1bb56": "EPP-3CCC-T3CD-X6ER",
    "2807e96ec8237817": "EPP-3J5W-B9BV-28GF",
}

Technical Analysis

Activation values function as bearer credentials: possession is sufficient to request activation. The package distributes one plaintext inventory in activation_codes.txt and another set of plaintext valid codes as values in VALID_HASHES.

The dictionary values are unnecessary for the implemented membership check because verification only tests whether a computed HMAC prefix exists among the dictionary keys. Storing the corresponding plaintext values directly defeats the purpose of hashing them.

The plaintext inventory is described by the source as unsold, meaning the package itself discloses credentials intended for future allocation. Any party able to download or inspect the Skill can copy these values.

Attack Path

  1. An attacker obtains the publicly or internally distributed Skill package.
  2. The attacker opens activation_codes.txt or reads VALID_HASHES in the verifier.
  3. The attacker copies a plaintext activation code.
  4. The attacker supplies the code to the activation workflow.
  5. If the code belongs to the verifier's accepted set or satisfies the legacy path, the verifier returns VALID and creates the activation marker.
  6. The P ...[truncated 404 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove activation_codes.txt from the distributed package and repository history.
  • Revoke every code that has been included in any released package.
  • Remove plaintext values from VALID_HASHES; a verifier must not contain the credentials it protects.
  • Prefer server-side activation over distributing a complete local credential database.
  • If offline activation is required, use digitally signed license documents and embed only the verification public key.
  • Add expiration, product scope, customer binding, and unique license identifiers to signed activation records.
  • Implement revocation and rate limiting for online activation.
  • Add secret-scanning rules to CI so activation inventories and bearer credentials cannot be committed again.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/verify_activation.py:116
Finding

Public Unkeyed Legacy Checksum Allows Activation-Code Forgery

Content
View full analysis

Vulnerability Details

File Location: scripts/verify_activation.py, lines 116-136 and 157-163
Vulnerability Type: Authentication bypass through a forgeable checksum
Risk Level: High

Vulnerable Snippet

python
LEGACY_CHARSET = list("23456789ABCDEFGHJKMNPQRSTUVWXYZ")

def legacy_verify(code):
    """Verify old-format codes with checksum algorithm"""
    code = code.strip().upper()
    parts = code.split("-")
    if len(parts) != 4 or parts[0] != "EPP":
        return False
    if len(parts[1]) != 4 or len(parts[2]) != 4 or len(parts[3]) != 4:
        return False
    try:
        chars = list(parts[1] + parts[2] + parts[3][:2])
        ascii_sum = sum(ord(c) for c in chars)
        cs_len = len(LEGACY_CHARSET)
        expected = LEGACY_CHARSET[ascii_sum % cs_len] + LEGACY_CHARSET[(ascii_sum // cs_len) % cs_len]
        return expected == parts[3][2:]
    except (ValueError, IndexError):
        return False

The result is accepted as a valid activation and persisted:

python
if legacy_verify(code):
    with open(MARKER, "w") as f:
        f.write(code)
    print("VALID")
    sys.exit(0)

Technical Analysis

The legacy verifier uses a deterministic, unkeyed checksum based only on the ASCII sum of attacker-controlled characters. Checksums can detect accidental corruption but cannot authenticate a credential.

Every component needed to create an accepted legacy code is public:

  • The required prefix and field lengths.
  • The accepted character set.
  • The characters included in the checksum.
  • The exact checksum calculation.
  • The acceptance and persistence behavior.

An attacker can choose the first ten checked characters, calculate the two required suffix characters, and produce a code accepted by legacy_verify. No secret, server interaction, purchase record, or digital signature is required.

Attack Path

  1. Choose arbitrary values for the ...[truncated 923 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove the legacy checksum fallback immediately.
  • Revoke all legacy-format activation codes.
  • Do not use checksums, hashes without secrets, or predictable arithmetic as authorization mechanisms.
  • For offline verification, issue licenses signed with a private key held outside the package and verify them with an embedded public key.
  • Include immutable claims such as product identifier, license identifier, expiration, and intended account or device in the signed payload.
  • For online verification, validate codes against a server-side database and enforce one-time redemption, rate limiting, and revocation.
  • Add negative tests proving that arbitrary attacker-selected prefixes cannot be converted into accepted credentials.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/verify_activation.py:9
Finding

Client-Side Secret and Plaintext Home-Directory Activation Marker

Content
View full analysis

Vulnerability Details

File Location: scripts/verify_activation.py, lines 9-10 and 139-163
Vulnerability Type: Hardcoded secret and insecure local credential storage
Risk Level: Medium

Vulnerable Snippet

python
SECRET = "decf0992110547bf1bc9350b6c4dec1e"
MARKER = os.path.expanduser("~/.exam-prep-pro.activated")
python
def verify(code):
    code = code.strip().upper()
    h = hmac.new(SECRET.encode(), code.encode(), hashlib.sha256).hexdigest()[:16]
    if h in VALID_HASHES:
        return True
    return False
python
if verify(code):
    with open(MARKER, "w") as f:
        f.write(code)
    print("VALID")
    sys.exit(0)

if legacy_verify(code):
    with open(MARKER, "w") as f:
        f.write(code)
    print("VALID")
    sys.exit(0)

Technical Analysis

The symmetric HMAC secret is embedded in code distributed to the party being authenticated. A client-side symmetric key cannot remain confidential because every recipient can inspect it. Although knowledge of this key alone does not add a new hash to the fixed VALID_HASHES collection, it exposes the verification design and prevents the key from serving as a meaningful trust boundary.

On successful activation, the raw code is written to ~/.exam-prep-pro.activated. The script does not explicitly request restrictive permissions, so effective permissions depend on the process umask. The file has no authenticated structure, integrity protection, expiration, or binding to a user or device.

The Skill documentation states that this marker is used to avoid future activation prompts. If downstream logic checks only for its existence, a local user can create it without running the verifier. The reviewed project does not include downstream marker-reading code, so this marker-spoofing impact is conditional on the documented trust model rather than a separately observed implementation.

Attack Path

1 ...[truncated 917 chars]

Remediation
View remediation

Remediation Suggestions

  • Replace symmetric client-side verification with asymmetric signatures; distribute only a public verification key.
  • Never write the raw activation code to disk after redemption.
  • Persist only minimal activation metadata, such as a signed license document or opaque server-issued token.
  • Create local state atomically with explicit mode 0600, for example by using os.open with restrictive flags and permissions.
  • Verify the integrity, product scope, expiration, and identity binding of persisted activation state on every use.
  • Do not treat marker-file existence alone as proof of authorization.
  • Avoid predictable dotfiles for security decisions unless their contents are cryptographically authenticated.
  • Rotate the exposed secret and invalidate artifacts generated under the old design.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose is exam preparation, but the skill embeds an unrelated monetization and activation workflow, including code verification and local state storage. This mismatch is dangerous because users and reviewers may trust the skill under an educational label while it performs operational behaviors that expand attack surface and can facilitate unauthorized persistence or payment collection.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill contains a payment-collection and activation-code sales funnel that is not necessary for providing exam-prep assistance. Embedding direct payment instructions and routing users to an external seller creates phishing, fraud, and social-engineering risk, especially because the workflow is framed as mandatory to unlock expected functionality.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

Requiring execution of a local verification script for activation-code validation is unrelated to normal exam-prep functionality and introduces an unnecessary code-execution pathway. Even if the named script is benign, this pattern normalizes local command execution based on conversational flow, which can be abused or substituted in less controlled environments.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill instructs persistent local file creation (~/.exam-prep-pro.activated) but does not declare any tool scope or permissions. That creates an undeclared capability boundary violation: a study-planning skill can modify the local environment without transparent authorization, which increases the chance of silent state changes or misuse.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest description says to use this skill whenever the user mentions a long list of broad terms such as "备考", "复习", "学习计划", and "重点", plus "任何与职业考试备考相关的需求". These phrases are common in everyday educational chat and the file does not provide exclusion conditions or negative examples, making unintended invocation more likely.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
78% confidence
Finding

The description and operating instructions are entirely in Chinese and present the assistant behavior as fixed in that language. There is no statement offering alternative languages or asking for the user's preferred language, which can violate language-choice policy when not clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The workflow asks users to send a payment screenshot to a seller without any privacy or identity warning. Payment receipts can contain names, account identifiers, timestamps, and transaction metadata, enabling privacy leakage or follow-on social engineering.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs creation of a persistent activation file in the user's home directory without disclosure or consent. Undisclosed persistence is dangerous because it silently alters the local environment, can leave artifacts containing sensitive license data, and conditions users to accept hidden state changes from a non-system utility skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The entire skill content, including headings and instructions, is written only in Chinese and does not indicate that users may choose another language. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is clearly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The entire skill file is written exclusively in Chinese and presents no indication that the user can choose another language or locale. Under the language/locale policy rule, a skill that effectively requires a specific language without opt-in can be a natural-language policy violation unless the constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest describes a职业考试备考 tool for study planning, review, and exam practice, but this file implements product activation verification and local license-state persistence. Licensing may be part of software distribution, but it is not behavior implied by the user-facing skill description and therefore exceeds the described operational scope.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file stores activation status by creating ~/.exam-prep-pro.activated and writing the supplied code to it after validation. Persisting licensing state in the user's home directory is not an obvious requirement for generating study plans, practice questions, or review assistance as described in the manifest.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script writes the raw activation code to a persistent file in the user's home directory without notice, which can expose a reusable license secret to other local processes, backups, or users depending on filesystem permissions. Even though this is not a remote compromise vector, storing sensitive tokens in plaintext creates avoidable credential leakage risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The document title and all instructional content are entirely in Chinese, with no indication that the user can choose another language or locale. Under the policy for natural-language constraints, forcing a single language without opt-in is a locale/language policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

This markdown file is entirely written in Chinese and does not indicate that language selection is optional or that the content is intentionally limited to a Chinese-speaking audience. Under the stated policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The entire skill is written in Chinese and presents its instructional content only in that language, with no indication that users may choose another language or that the skill is intentionally limited to a Chinese-language audience. Under the stated policy, forcing a specific language without opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

This markdown file presents all instructional content in a single language and does not indicate that the user can opt into another language. Under the stated policy, forcing a specific language without user choice can be a natural-language policy violation unless the locale constraint is explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

SQP-3 applies to all file types and covers language or locale policy violations. This markdown file presents all instructions and content in Chinese without any opt-in, alternative language option, or justification that the skill is region-specific, which can be interpreted as forcing a specific language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

This markdown file contains user-facing instructional content exclusively in Chinese, with no opt-in, alternative locale, or justification for the language constraint. Under the policy, forcing a specific language without user choice can be a natural-language locale violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file presents all instructional content in a single language and does not provide any user opt-in or alternative locale. Under the policy rule, forcing a specific language without choice can be a natural-language policy violation unless the locale constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.