Back to skill

Security audit

手机检测

Security checks for vulnerabilities and agentic risk

Overview

This phone-detection skill appears to use an external API, but it stores the API key insecurely and contains mismatched configuration from another service, so it needs review before installation.

Install only if you are comfortable sending image URLs or full image contents and an API key to Xiaobenyang. Prefer a restricted or disposable API key, avoid sensitive images, and ask the publisher to replace .env plaintext persistence with secure secret storage, validate API keys, remove the gaokao leftovers, disclose remote data handling, and pin dependencies.

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

Error
Location
scripts/config.py:40
Finding

API Key Stored in Plaintext with Dotenv Injection Risk

Content
View full analysis
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 def set_api_key(api_key: str) -> bool: """设置API key并持久化到.env""" if not api_key or not api_key.strip(): return False api_key = api_key.strip() if not save_api_key_to_env(api_key): return False # 更新全局 settings 实例 settings.api_key = api_key return True ``` ### Technical Analysis The API key is written directly to `.env` as plaintext. The code does not create the file with explicit restrictive permissions, so its confidentiality depends on the process umask and pre-existing file permissions. More critically, `set_api_key()` only rejects empty values. Calling `strip()` removes leading and trailing whitespace but does not reject embedded carriage-return or newline characters. Consequently, an attacker-controlled key can append additional dotenv assignments. This is security-sensitive because `Settings` loads variables with the `XBY_GAOKAO_` prefix from `.env`. An injected assignment such as `XBY_GAOKAO_BASE_URL` can therefore ...[truncated 1835 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Dependencies Are Not Reproducibly Pinned or Integrity-Verified

Content
View full analysis
=2.31.0 pydantic>=2.7.0 pydantic-settings>=2.2.0 python-dotenv>=1.0.1 ``` ### Technical Analysis Every dependency is declared using only a minimum version. There are no exact version pins, upper bounds, lock file entries, or package hashes. A future package version satisfying the lower bound can therefore be selected without having been reviewed with this project. This does not establish that any currently listed package is malicious. It creates a supply-chain weakness because installation behavior can change over time and can incorporate a subsequently compromised, malicious, or incompatible release. ### Attack Path 1. A future release of one of the declared packages is compromised, malicious, or otherwise unsafe. 2. The release remains compatible with the broad `>=` requirement. 3. A user or deployment system installs the project without a previously reviewed lock file or hash enforcement. 4. The package resolver selects the new release. 5. Package installation or import executes the affected dependency code with the privileges of the installing or running process. Exploitation depends on compromise or unsafe publication of an allowed upstream release; no such compromise was confirmed during this source audit. ### Impact Assessment The resulting code would run with the same operating-system privileges as the installation or Skill runtime process. Depending on the compromised dependency, impact could include: - Access to the API key held in memory, environment variables, or `.env`. - Reading or modifying files accessible to the process. - Exfiltration of image data and application configuration. - Arbitrary network communication. - Arbitrary code execution within the process's privilege boundary. The broad version ranges also make ...[truncated 109 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
99% confidence
Finding

The skill says it performs phone detection, but the specification also indicates reading and persisting API credentials, remote configuration management, and even references to gaokao-related infrastructure unrelated to this task. Such cross-purpose behavior suggests code or documentation reuse without proper isolation, which can expose secrets, route data to unintended services, or cause users to authorize capabilities they would not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill says it performs phone detection, but the specification also indicates reading and persisting API credentials, remote configuration management, and even references to gaokao-related infrastructure unrelated to this task. Such cross-purpose behavior suggests code or documentation reuse without proper isolation, which can expose secrets, route data to unintended services, or cause users to authorize capabilities they would not expect.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The configuration clearly belongs to an unrelated '小笨羊高考' service and includes API endpoint, MCP ID, and API-key handling that do not match the declared phone-detection purpose. This mismatch strongly suggests copied or repurposed code that could cause the skill to collect or route credentials to an unrelated external service, expanding trust boundaries without justification.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
89% confidence
Finding

Loading secrets from a .env file is a credential-handling behavior, and in this skill it is not justified by the declared image-detection purpose. The risk is elevated because the same module is tied to an unrelated external service, making secret collection and use harder to justify or audit.

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 method forcibly reads XBY_APIKEY directly from .env, bypassing normal least-privilege patterns and explicitly searching for a credential for an unrelated service. This behavior increases the chance of unauthorized credential harvesting from the local workspace when the skill is initialized.

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

The code opens and reads the .env file contents directly, which is sensitive because .env commonly stores multiple credentials beyond the single key being sought. In the context of a phone-detection skill, direct credential-file access is unnecessary and materially broadens the data the skill can inspect.

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

The code explicitly prioritizes an environment variable named XBY_APIKEY associated with the unrelated service, continuing the pattern of handling credentials outside the declared scope of the skill. This can expose secrets to misuse by shared runtime components and obscures what external service the skill may contact.

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 skill writes API credentials to a local .env file and mirrors them into process environment variables even though its stated purpose is image-based phone detection. Persisting secrets unnecessarily increases exposure through local file disclosure, accidental source control inclusion, logs, backups, or reuse by unrelated components in the same runtime.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The function save_api_key_to_env is dedicated to persisting credentials to disk, which creates a durable secret exposure surface. In a skill that should only detect phones in an image, credential persistence is out of scope and especially concerning because it targets a different service domain entirely.

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

The skill declares no explicit tool/permission scope even though it appears to rely on environment access, file reads/writes, and network access. In a skill that also collects and persists secrets, missing scope boundaries increases the chance of over-privileged execution and makes review and enforcement harder.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs the agent to request an API key from the user and persist it via configuration without clearly warning about sensitivity, storage, retention, or access controls. This is dangerous because users may disclose a secret in an unsafe channel, and persistent storage in .env or local files can expose credentials to other skills, logs, backups, or unintended operators.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code presents user-facing behavior and error/messages exclusively in Chinese, including the class/function docstrings and returned error text such as "API密钥未设置" and "API调用失败". Under the policy, forcing a specific language without user opt-in or a clearly documented region-specific justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The class docstring identifies the module as configuration for a different skill, contradicting the manifest and reinforcing that this file was reused from another project. In a security review, this identity mismatch matters because it undermines provenance and suggests hidden functionality or dependencies that users would not expect from a phone-detection skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code persists an API key to .env without any visible user confirmation, warning, or consent flow. Even if secret storage were otherwise intended, silent persistence can surprise users and cause long-lived credential exposure on disk where other tools, users, or processes may access it.

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-supplied image URL to an external API via call_api, but the skill text and function interface do not provide any user-facing disclosure that image-related data will leave the local environment. This creates a privacy and data-handling risk because users may provide sensitive images or internal URLs without understanding that the content or referenced resource will be processed by a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This function transmits raw base64-encoded image content to an external API, which means the full image data is disclosed off-system. Without a clear warning, consent flow, or data-handling notice, users may unknowingly upload sensitive images containing personal, confidential, or regulated information.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The entire skill name and user-facing instructions are written only in Chinese, with no indication that the user may choose another language or locale. Under the policy, forcing a specific language without opt-in can be a natural-language policy violation unless the locale restriction is clearly documented and justified.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill claims its only purpose is detecting phones in images, and the tool list below only documents cellphone_detection functions. The example call instead uses scripts.tools.search_schools(...), which actively contradicts the documented intent and could cause an agent to invoke an unrelated capability.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest and the rest of the document consistently describe a 手机检测 skill, but the project structure block names the package xiaobenyang_gaokao_skill. This is not merely incomplete documentation; it points to a different skill identity and can mislead operators about what codebase or tooling is actually being used.

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 version only, which makes builds non-reproducible and allows future installs to resolve to different releases. That increases supply-chain risk and makes it impossible to determine whether a deployed version includes known vulnerable code or breaking changes.

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

The manifest does not pin requests, and the package has multiple known advisories across versions, so the actual installed version cannot be verified as safe. Because requests commonly handles outbound HTTP, affected versions could expose credentials, TLS verification behavior, or other network security properties if a vulnerable release is resolved.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

Using pydantic>=2.7.0 without an upper bound or exact pin leaves dependency resolution open-ended. This weakens reproducibility and can silently introduce vulnerable or incompatible releases into the environment.

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

Because pydantic is not pinned, there is no way to prove the deployed version is outside the set of known vulnerable releases. In practice this creates uncertainty around issues such as denial of service or parsing flaws, though the impact here appears lower without evidence of attacker-controlled complex validation paths in this file.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The unpinned pydantic-settings requirement permits installation of any later version, preventing deterministic builds and increasing supply-chain uncertainty. If a later release is compromised or vulnerable, installations may inherit that risk automatically.

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

The requirement for pydantic-settings is unpinned despite known advisories in some versions, so the environment may resolve to an affected release. This is mainly a supply-chain and configuration-hardening problem in this manifest, with no direct exploit path shown here.

Content

No source excerpt is available for this finding.