Back to skill

Security audit

AWS Black Belt服务

Security checks for vulnerabilities and agentic risk

Overview

The skill appears intended to search AWS Black Belt seminars, but it asks users for a third-party API key, stores it in plaintext, and includes mismatched reused Gaokao/XiaoBenYang code that broadens review risk.

Review before installing. Only use this skill if you trust xiaobenyang.com with the API key and requests, and prefer a disposable or least-privilege key. Be aware it will save the key in a local plaintext .env file unless changed, and the package contains stale unrelated Gaokao references plus a broad upstream MCP wrapper.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:45
Finding

API Key Persisted in a Plaintext File Without Explicit Access Controls

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py, lines 45-65
Vulnerability Type: Plaintext storage of sensitive credentials
Risk Level: Medium

Vulnerable Code

python
def save_api_key_to_env(api_key: str) -> bool:
    """将API key保存到.env文件"""
    try:
        env_path = Path(".env")
        lines = []
        if env_path.exists():
            lines = env_path.read_text(encoding="utf-8").splitlines()
        found = False
        new_lines = []
        for line in lines:
            if line.startswith("XBY_APIKEY="):
                new_lines.append(f"XBY_APIKEY={api_key}")
                found = True
            else:
                new_lines.append(line)
        if not found:
            new_lines.append(f"XBY_APIKEY={api_key}")
        env_path.write_text("\n".join(new_lines) + "\n", encoding="utf-8")
        os.environ["XBY_APIKEY"] = api_key
        return True
    except Exception as e:
        print(f"保存API key失败: {e}")
        return False

Technical Analysis

The function stores a user-provided API key directly in a plaintext .env file. It does not explicitly create or enforce restrictive file permissions. The file path is also relative to the process working directory rather than a dedicated, validated configuration directory.

Consequently, the secret may be written into an unintended project directory and become accessible to other local users or processes according to the effective directory permissions and process umask. It may also be included in source-control commits, archives, backups, or diagnostic bundles.

The API client later uses this credential in the XBY-APIKEY request header. Exposure therefore permits use of the affected user's API identity within the authorization scope assigned by the remote service.

Attack Path

  1. The Skill asks the user to provide an API key.
  2. set_api_key() passes that key to `save_api_key_t ...[truncated 1018 chars]
Remediation
View remediation

Remediation Suggestions

  1. Prefer session-only credential handling or a platform-provided secret manager or operating-system keyring.
  2. Obtain explicit user consent before persisting the key.
  3. Store persistent configuration in a dedicated per-user configuration directory rather than the current working directory.
  4. Create the secret file atomically with owner-only permissions, such as mode 0600 on POSIX systems, and verify existing-file ownership and permissions before modifying it.
  5. Ensure .env is excluded from version control, packaging, backups, logs, and diagnostic exports.
  6. Avoid retaining the credential in more locations than necessary.
  7. Provide key rotation and deletion functionality, and instruct affected users to revoke any credential that may already have been exposed.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unbounded Third-Party Dependency Versions Create Supply-Chain and Reproducibility Risk

Content
View full analysis

Vulnerability Details

File Location: requirements.txt, lines 1-4
Vulnerability Type: Unlocked dependency resolution
Risk Level: Low

Vulnerable Code

text
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1

Technical Analysis

Every dependency uses a minimum-only version constraint. There are no exact version pins, upper bounds, integrity hashes, or reviewed lock file. A fresh installation can therefore resolve to package versions that were not present when the Skill was audited.

This is not evidence that any currently named package is malicious. The risk arises because future compromised, vulnerable, or incompatible releases can be selected automatically. Python packages may execute code during installation, and imported dependencies execute with the privileges of the process running the Skill.

Attack Path

  1. An operator installs the project dependencies at a later date.
  2. The package resolver selects newer releases permitted by the minimum-only constraints.
  3. One selected release has been compromised, contains a newly introduced vulnerability, or behaves incompatibly.
  4. Malicious installation logic or runtime package code executes when the package is installed or imported.
  5. That code operates with the permissions and environmental access of the installing or Skill-hosting process.

Exploitation is contingent on a compromised or vulnerable future dependency release; the audit found no proof that the currently referenced package names are malicious or typosquatted.

Impact Assessment

A compromised dependency could potentially read files and environment variables available to the process, including the configured API key, make network requests, alter application behavior, or execute code with the process user's privileges. The precise scope depends on the installation environment and the permissions under which dependency installati ...[truncated 29 chars]

Remediation
View remediation

Remediation Suggestions

  1. Generate and commit a reviewed lock file containing exact dependency versions.
  2. Require cryptographic hashes for downloaded distributions, for example by using a hash-locked requirements file.
  3. Separate direct dependencies from fully resolved transitive dependencies.
  4. Update dependencies through a controlled process that includes vulnerability scanning, changelog review, and automated testing.
  5. Install packages from a trusted, explicitly configured package index.
  6. Perform dependency installation in an isolated, least-privileged environment rather than with administrative permissions.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (35)

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill presents itself as an AWS seminar utility, yet it instructs collection and persistence of an unrelated API key and references inconsistent service naming such as xiaobenyang/gaokao. This is a strong trust-boundary mismatch that can conceal credential harvesting or unintended data flow to a third-party service unrelated to the advertised function.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill presents itself as an AWS seminar utility, yet it instructs collection and persistence of an unrelated API key and references inconsistent service naming such as xiaobenyang/gaokao. This is a strong trust-boundary mismatch that can conceal credential harvesting or unintended data flow to a third-party service unrelated to the advertised function.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The call_tool method accepts caller-controlled tool_name, mcp_id, and params and forwards them directly to the upstream service, effectively enabling arbitrary upstream tool invocation. In the context of a skill advertised only for AWS Black Belt search/transcript retrieval, this excessive authority can let a prompt, user, or chained component trigger unintended remote actions or access broader data/functions than expected.

Content

No source excerpt is available for this finding.

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

python
model_config = SettingsConfigDict(
        env_prefix="XBY_GAOKAO_",
        env_file=".env",
        env_file_encoding="utf-8",
        extra="ignore",
    )

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The model_post_init method forcibly reads XBY_APIKEY from the local .env file, implementing explicit secret ingestion unrelated to the skill’s declared AWS Black Belt purpose. In this context, the mismatch in service identity and secret name increases concern that the skill is harvesting or reusing credentials from an unrelated ecosystem.

Content

Scanner excerpt · scripts/config.py (reported line 31)May include surrounding context.

python
default_year: int = 2025

    def model_post_init(self, __context):
        # 强制从 .env 文件读取 XBY_APIKEY
        env_path = Path(".env")
        if env_path.exists():
            content = env_path.read_text(encoding="utf-8")

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The explicit existence check and subsequent read of .env is part of a custom secret-access path that bypasses user expectations and broadens the skill’s ability to inspect local credentials. Given the manifest mismatch and unrelated XBY_APIKEY naming, this behavior is more dangerous than ordinary configuration loading.

Content

Scanner excerpt · scripts/config.py (reported line 32)May include surrounding context.

python
def model_post_init(self, __context):
        # 强制从 .env 文件读取 XBY_APIKEY
        env_path = Path(".env")
        if env_path.exists():
            content = env_path.read_text(encoding="utf-8")
            for line in content.splitlines():

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

This line loads a locally stored XBY_APIKEY into the active settings object, enabling the skill to use a secret sourced from an unrelated local environment. In the context of an AWS seminar search skill, importing and activating a different service’s API key is suspicious and can facilitate unauthorized access or hidden outbound requests.

Content

Scanner excerpt · scripts/config.py (reported line 39)May include surrounding context.

python
if line.startswith("XBY_APIKEY="):
                    self.api_key = line.split("=", 1)[1].strip()
                    break
        # 如果环境变量有值,覆盖 .env 的值
        env_val = os.getenv("XBY_APIKEY", "")
        if env_val:
            self.api_key = env_val

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

This file implements API credential persistence and retrieval logic that is unrelated to the stated AWS Black Belt search/transcript function. Storing secrets in a local .env file expands the attack surface, creates unnecessary secret-handling capability, and indicates the skill may collect or retain credentials beyond what users would expect from its manifest.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The save_api_key_to_env function writes API keys directly into .env, creating local secret-storage capability not justified by a seminar search/transcript skill. This can expose credentials through weak file permissions, accidental check-in, backups, logs, or other local disclosure paths.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The function is explicitly designed to save an API key into .env, which is a direct secret persistence mechanism. This creates durable local exposure of credentials and is especially problematic here because the capability is not justified by the manifest and may retain sensitive tokens without informed consent.

Content

Scanner excerpt · scripts/config.py (reported line 48)May include surrounding context.

python
def save_api_key_to_env(api_key: str) -> bool:
    """将API key保存到.env文件"""
    try:
        env_path = Path(".env")
        lines = []
        if env_path.exists():
            lines = env_path.read_text(encoding="utf-8").splitlines()

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill declares no explicit tool scope or permission boundaries even though its documented behavior includes environment access, file reads/writes, and network use. In an agent setting, missing scope declarations increase the risk of overbroad execution and make it harder to constrain secret handling, persistence, and outbound requests.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill explicitly instructs the model to ask the user for an API key and persist it via configuration. Having the conversational agent collect secrets directly is dangerous because users may disclose credentials in chat, and local persistence in .env or similar files increases the chance of leakage, reuse, or unintended access by other skills/processes.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The workflow repeatedly normalizes prompting the user for missing API keys before proceeding, reinforcing unsafe secret-collection behavior. In the context of an agent skill, this increases the likelihood of credential phishing patterns and trains users to hand sensitive tokens to a chat interface tied to a vaguely described third-party backend.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

Residual 'search_schools/gaokao' workflow and project-structure references indicate the skill may be repurposed from a different project without being fully updated. Such inconsistencies are dangerous because they suggest hidden or unintended functionality and reduce confidence that the documented behavior matches the actual operations performed.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The markdown explicitly states 'Supported only in Japanese' for transcript retrieval, which imposes a language constraint in the skill behavior. The file does not offer an opt-in choice for language support beyond the fixed Japanese limitation, nor does it justify this as a region-specific or compliance-driven constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The parameter documentation sets the default transcript language to 'ja' for Japanese, which creates a forced locale behavior unless the user overrides it. Under the policy, language constraints should be opt-in or clearly justified, and this file does not provide that justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The tool description again states that transcript support is only available in Japanese. This is a natural-language locale restriction and, as written, it is not accompanied by user choice or a documented justification that would exempt it under the policy.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation specifies a default language code of 'ja' for transcript retrieval, which enforces a locale preference absent explicit user consent. The file does not indicate that users are prompted about language preference or that the default is justified by a narrow regional context.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The guidance to directly present raw API response data to the user is unsafe because upstream responses may contain sensitive fields, internal identifiers, unexpected HTML/Markdown, or prompt-injection content. Returning raw data without validation or sanitization can leak secrets and relay malicious content from external services into the conversation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The implementation is a generic wrapper for an external MCP API and is not constrained to the advertised AWS Black Belt seminar search/transcript purpose. This creates a capability mismatch: operators or downstream callers may believe the skill is narrowly scoped, while the code can be repurposed to invoke unrelated upstream functionality through arbitrary headers and parameters.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code accesses a credential via get_api_key() and sends it in the XBY-APIKEY header during a network request. While the module has internal logging and Chinese docstrings, there is no confirmation prompt or explicit user-facing warning that credentials and request data will be sent to an upstream service.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The class docstring describes a different skill ('小笨羊高考Skill配置') than the manifest’s AWS Black Belt service, which is a strong integrity and provenance mismatch. Such inconsistencies are suspicious because they can conceal code reuse from unrelated projects, mislead reviewers, and mask unauthorized credential or network behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

API keys are persisted to .env automatically with no user-facing warning, confirmation, or disclosure of retention. This is dangerous because users may provide a secret for transient use but the skill silently stores it on disk, increasing the chance of later compromise or unauthorized reuse.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The function get_seminar_transcript sets the default language to "ja" and its docstring states transcripts are supported only in Japanese. This imposes a specific language/locale by default rather than offering a user choice or making opt-in explicit, which matches the language-policy concern for this rule.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.