Back to skill

Security audit

香烟检测

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to use a remote API for cigarette detection, but it stores API keys in plaintext and can send keys and images to a configurable endpoint.

Review before installing. Use only non-sensitive images, do not provide an API key you cannot rotate, and avoid running this skill in a workspace where .env files may be committed, backed up, or shared. The publisher should remove the Gaokao leftovers, validate or pin the upstream API host, avoid plaintext key persistence, and clearly disclose that images are sent to Xiaobenyang's remote service.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/call_api.py:52
Finding

Configurable API Endpoint Can Expose Credentials and Submitted Images

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:42
Finding

API Key Is Persisted in a Plaintext Environment File Without Explicit Permission Hardening

Content
View full analysis
bool: """Save the API key to the .env file.""" 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"Failed to save API key: {e}") return False ``` ### Technical Analysis The API key is written directly into `.env` as plaintext. The implementation does not explicitly create or verify the file with owner-only permissions, verify file ownership, or protect the credential using an operating-system secret store. The effective permissions depend on the process umask and any pre-existing file permissions. If `.env` already exists with permissive access, rewriting it does not necessarily correct those permissions. The credential can also be exposed through project backups, workspace archives, container layers, or accidental source-control inclusion. The same key is additionally copied into the process environment, making it available to code executing within the process and potentially to diagnostic tooling with sufficient access. ### Attack Path 1. A user supplies an API key as required by the Skill workflow. 2. `set_api_key` calls `save_api_key_to_env`. 3. The function writes `XBY_APIKEY=` into `.e ...[truncated 903 chars]
Remediation
View remediation
Vulnerability Patterns
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill documentation references reading/writing .env files, persisting API keys, loading credentials from environment variables, and even unrelated gaokao/default-year configuration, which is materially inconsistent with a narrowly scoped image-detection skill. This broadens the attack surface and suggests code reuse or hidden functionality that could mishandle secrets or perform actions unrelated to the user’s request.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill documentation references reading/writing .env files, persisting API keys, loading credentials from environment variables, and even unrelated gaokao/default-year configuration, which is materially inconsistent with a narrowly scoped image-detection skill. This broadens the attack surface and suggests code reuse or hidden functionality that could mishandle secrets or perform actions unrelated to the user’s request.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file for a cigarette-detection skill contains configuration for an unrelated Gaokao/MCP service, including base URL, MCP identifier, and API-key handling. This capability mismatch is dangerous because it introduces unexplained network/service integration and credential handling that are not required for the stated image-detection purpose, increasing the risk of hidden data flow or unauthorized service access.

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

The model_post_init routine explicitly reads .env and extracts XBY_APIKEY manually, creating custom credential-loading logic beyond normal framework behavior. In the context of an image-detection skill, this unexplained secret harvesting is high risk because it widens access to credentials and bypasses clearer, centralized secret-management patterns.

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 code checks for the existence of .env and reads its contents directly, which is part of a custom credential access path. In this mismatched skill context, directly inspecting a sensitive configuration file is suspicious because the advertised function does not require managing external service credentials, making hidden or unnecessary secret access more dangerous.

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

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code can persist an API key into a local .env file and reuse it later, even though the declared purpose is image-based cigarette detection. Storing credentials on disk without a clear operational need broadens secret exposure through source packaging, backups, logs, or accidental inclusion in repositories, and creates a hidden persistence mechanism in a low-trust skill context.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

This function is explicitly designed to save an API key into .env, establishing durable credential persistence in the skill's working directory. In a skill whose stated purpose is object detection from images, this is an unnecessary credential-handling capability that increases the chance of secret leakage through files, packaging, backups, or repository commits.

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

The skill declares no explicit tool or permission scope even though its documented/project capabilities include environment access, file read/write, and network use. Without least-privilege boundaries, a consumer cannot easily determine or constrain what the skill may access, increasing the risk of credential handling abuse or unintended data exposure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

References to unrelated gaokao/search functionality inside a cigarette-detection skill indicate copy-paste drift or mixed-purpose tooling. Such inconsistencies are dangerous because they can misroute user input, invoke the wrong tools, or conceal broader capabilities than users expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill asks users to provide image URLs or Base64 image data but does not warn that this content will be transmitted to an external service. Users may unknowingly send sensitive images or internal URLs to a third party, creating privacy, confidentiality, and potential SSRF-like risk depending on how remote fetching is implemented.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Instructing the agent to directly display raw API responses can expose sensitive or unnecessary data, including user-submitted image-derived content, internal identifiers, verbose error traces, or echoed request metadata. Raw output bypasses minimization and redaction, making accidental disclosure more likely.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code sends the provided params to a remote endpoint and includes a credential in the request headers. The file contains no confirmation prompt, print/log statement informing the user that data will be transmitted externally, and no inline warning near the operation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The docstring identifies the code as a '小笨羊高考Skill配置', which conflicts with the manifest claiming cigarette detection. This inconsistency is a strong trust and provenance warning: it suggests code reuse or substitution from another project, making hidden functionality and mis-scoped permissions more likely in a security review.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function writes the supplied API key to .env and exports it into the process environment with no user-facing warning, confirmation, or security controls. This is risky because users may unknowingly cause long-lived credential persistence, and other components in the same runtime may subsequently access the secret from the environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The function sends a user-provided image URL to an external API endpoint via call_api, but this file provides no disclosure, consent handling, or indication to callers that image content will leave the local environment. Because images may contain sensitive visual data, silent transmission to a third-party service creates a real privacy and data-governance risk even if the code is otherwise straightforward.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This function transmits raw base64-encoded image content to an external API without any visible user warning or disclosure in the file. Sending the full image bytes off-box is more privacy-sensitive than passing a reference, since the entire potentially sensitive image is directly exfiltrated to a remote service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The entire skill name and instructions are written only in Chinese, with no indication that users may choose another language or that the locale limitation is required for a region-specific compliance reason. This can violate language/locale policy when a skill implicitly mandates one language without opt-in.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency specification uses a lower-bound only constraint (requests>=2.31.0), which makes builds non-reproducible and allows future installs to resolve to unexpected versions. This increases supply-chain risk and makes it impossible to determine from the manifest alone whether a vulnerable or incompatible release will be installed.

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

requests has multiple known advisories, but the manifest does not pin the installed version, so exposure cannot be verified. This is dangerous because an environment may resolve to an affected release, especially in CI/CD or redeployments where dependency state changes over time.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

pydantic>=2.7.0 is unpinned, so dependency resolution may pull different versions over time across environments. That weakens build integrity and can silently introduce vulnerable or breaking releases into the skill.

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

Unverifiable Dependency: pydantic has 4 known advisory(ies) (CVE-2021-29510 (Use of "infinity" as an input to datetime and date fields causes infinite loop i); CVE-2024-3772 (Pydantic regular expression denial of service); CVE-2021-29510 (Pydantic is a data validation and settings management using Python type hinting.) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding

pydantic has known advisories, and without exact version pinning there is no reliable way to assess whether deployed environments are vulnerable. This creates a real but low-severity supply-chain risk because the package selected at install time may differ from what was tested.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

pydantic-settings>=2.2.0 permits any newer version, making installations non-deterministic. In a security context, that means potentially affected versions could be installed later without any manifest change.

Content

Scanner excerpt · requirements.txt (reported line 3)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: pydantic-settings has 1 known advisory(ies) (CVE-2026-58203 (pydantic-settings: NestedSecretsSettingsSource follows symlinks outside secrets_)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding

pydantic-settings is listed with a known advisory, and the lack of a fixed version means the actual security posture is unverifiable from this file. Even if the current environment happens to be safe, future installs could select an affected version.

Content

No source excerpt is available for this finding.