Back to skill

Security audit

Logo提取处理工具

Security checks for vulnerabilities and agentic risk

Overview

This logo skill calls a remote API, but its code and documentation are inconsistent and it stores your API key in a local plaintext .env file without enough safeguards.

Review carefully before installing. Use a limited-scope XiaoBenYang API key, avoid sharing high-value credentials, and assume the key may be stored in plaintext in the working directory. The skill should ideally use a secret store or session-only configuration, document exactly what is sent to the remote API, and remove the unrelated gaokao references before normal 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/config.py:41
Finding

API Credential Persisted in a Plaintext Environment File

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py, lines 41–63
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

Technical Analysis

The function persistently writes the user-provided API key to a plaintext .env file. It neither creates the file with an explicit owner-only permission mode nor validates or corrects the permissions of an existing file. Consequently, confidentiality depends on the process umask and the existing filesystem permissions.

The implementation also follows the .env path without checking whether it is a symbolic link and replaces the file non-atomically. A local attacker with suitable access to the working directory could potentially redirect the write or observe the credential during file operations. Because the project does not include a .gitignore, the stored secret may also be accidentally committed or captured by backups and artifact collection.

Attack Path

  1. A user supplies an API key as directed by the Skill documentation.
  2. The Agent invokes set_api_key(), which calls save_api_key_to_env().
  3. The function stores the key as XBY_APIKEY=<secret> in the working directory’s .env file.
  4. A local user or process wit ...[truncated 1086 chars]
Remediation
View remediation

Remediation Suggestions

  1. Prefer session-only secret handling or an operating-system credential manager instead of persistent plaintext storage.
  2. Obtain explicit user consent before persisting the API key.
  3. If file persistence is unavoidable, create the secret file with owner-only permissions (0600) and verify or correct the permissions of existing files before reading or writing them.
  4. Reject symbolic links and ensure the resolved destination is the intended regular file inside the expected project directory.
  5. Write updates atomically through a securely created temporary file in the same directory, apply restrictive permissions, and then replace the destination.
  6. Add .env to .gitignore and exclude it from packaging, logging, backups, diagnostics, and artifact collection.
  7. Avoid retaining duplicate copies of the credential longer than necessary and never include it in exception messages.
  8. Document credential rotation procedures so users can promptly revoke and replace an exposed key.
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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (33)

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 claims broader image-processing and vector-conversion capabilities that are not reflected in the documented tools, suggesting overstatement or copied documentation. While this is not direct code execution, such misrepresentation can mislead reviewers and users into granting trust to a skill whose real behavior is narrower and externally delegated.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims broader image-processing and vector-conversion capabilities that are not reflected in the documented tools, suggesting overstatement or copied documentation. While this is not direct code execution, such misrepresentation can mislead reviewers and users into granting trust to a skill whose real behavior is narrower and externally delegated.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The skill claims broader image-processing and vector-conversion capabilities that are not reflected in the documented tools, suggesting overstatement or copied documentation. While this is not direct code execution, such misrepresentation can mislead reviewers and users into granting trust to a skill whose real behavior is narrower and externally delegated.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file’s behavior is materially inconsistent with the declared Logo extraction tool: it implements configuration and persistence for an unrelated remote API and stores credentials locally. In agent skills, this kind of scope mismatch is dangerous because it can hide unauthorized data handling or secret collection under an unrelated description, reducing user scrutiny and enabling credential misuse.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The class docstring identifies the code as a different skill entirely, which directly conflicts with the stated Logo-processing purpose. This mismatch is a strong trust and provenance red flag because it suggests copied or repurposed code that may perform undeclared actions, including secret handling unrelated to the advertised functionality.

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
82% confidence
Finding

This logic forcibly reads XBY_APIKEY from .env during initialization, including for a skill whose declared purpose does not justify such credential handling. In the context of a mismatched agent skill, undeclared secret ingestion is dangerous because it collects and uses credentials outside user expectations and may facilitate access to an unrelated remote service.

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
82% confidence
Finding

Reading the .env file contents directly bypasses more controlled secret-management patterns and enables explicit parsing of credentials from local storage. In this skill context, the behavior is more suspicious because the tool description does not prepare users for unrelated API key collection or usage.

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
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 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

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

This function explicitly persists an API key into a local .env file, creating a durable secret artifact within the project environment. In an agent skill with unrelated stated functionality, local credential storage is more dangerous because it suggests hidden secret retention that could be exfiltrated, accidentally committed, or accessed by other tooling.

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
91% confidence
Finding

The skill declares no explicit tool scope or permission boundaries while its documented/project capabilities imply access to environment variables, local files, file writes, and network calls. In an agent setting, missing scope declarations increases the chance of overbroad execution and makes it harder to constrain credential access and persistence behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation promises extraction, processing, and vector conversion, but only documents URL retrieval and metadata analysis. Security-relevant documentation inconsistencies matter because they obscure what the skill actually does and can hide that processing is delegated to an external API instead of performed locally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill instructs the agent to ask the user for an API key and persist it via set_api_key without any warning, consent flow, retention limits, or secure storage guidance. Collecting and storing credentials in this manner can expose secrets to logs, local files, or other skills/processes, especially because the documented storage target is .env.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

References to unrelated gaokao and search_schools functionality indicate copy-paste residue or code repurposing inconsistent with the stated logo-extraction purpose. This kind of contradiction is risky because it suggests the skill may contain hidden or unintended behaviors, and reviewers cannot reliably determine the true operational scope.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The instruction to directly display result["raw"] to the user is unsafe because raw API responses can contain unexpected fields, internal metadata, reflected secrets, or error traces. In an agent workflow, unfiltered passthrough also increases the risk of prompt injection content or sensitive third-party data being surfaced verbatim.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This file includes user-facing docstrings and error/message strings in Chinese, such as the class/docstring text and returned error messages, with no indication that the skill is region-specific or that users can opt into another language. That creates a natural-language locale policy issue because the skill appears to enforce a specific language by default.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The code adds the ability to persist an API key into a local .env file even though that is not clearly necessary for Logo extraction. Persisting secrets to disk expands the attack surface by leaving credentials recoverable from the workspace, backups, source archives, or accidental commits, especially in multi-tenant or agent-managed environments.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The save path writes sensitive API material to .env without any user-facing warning, confirmation, or disclosure in this code path. Silent secret persistence is risky because users may assume a transient in-memory configuration while the credential is actually being stored on disk and potentially exposed to other processes, users, or version control mistakes.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

SQP-3 applies to all file types and includes language or locale policy violations. The user-facing docstrings are exclusively in Chinese and do not offer any language choice or indicate that the skill is intentionally region-specific, which can force a specific language on users without opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The natural-language text for this function is likewise only in Chinese, with no alternative language or opt-in. Under SQP-3, forcing a single language without user choice is a policy concern unless the locale restriction is clearly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

All user-facing instructions and operational requirements are presented only in Chinese, and the document does not indicate that the skill is region-specific or that users may choose another language. Under the stated policy, forcing a specific language without opt-in can be a natural-language policy issue.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified with a lower bound only, which allows future installs to resolve to different versions over time. This weakens supply-chain control and makes builds non-reproducible, increasing the chance of pulling in a vulnerable or incompatible release of requests.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

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

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
88% confidence
Finding

requests has multiple known advisories, and because the manifest does not pin the package, it is impossible to verify whether deployed environments are using a fixed or affected version. In a tool that fetches remote website content by URL, dependency hygiene matters more because network-facing behavior increases exposure to issues in the HTTP client stack.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

Using pydantic>=2.7.0 leaves the exact installed version undefined, so different environments may install different releases. That creates supply-chain uncertainty and can expose deployments to newly introduced vulnerable versions without any change to this repository.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

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