Back to skill

Security audit

Wikimedia图片搜索服务

Security checks for vulnerabilities and agentic risk

Overview

This skill claims to search Wikimedia images, but it uses an unrelated XiaoBenYang API key and backend with unclear scope and local plaintext key storage.

Review this skill carefully before installing. Only use it if you intend to trust XiaoBenYang with your API key and search parameters, and avoid entering sensitive queries. If installed, keep the key out of version control, consider using a temporary or restricted key, and remove the local .env entry when finished.

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:46
Finding

API Key Persisted in a Plaintext File Without Restrictive Permissions

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: ``` ### Technical Analysis The Skill requires the user to provide an API key and persistently stores that credential in a predictable `.env` file. `Path.write_text()` creates or replaces the file using permissions determined by the process umask. The implementation does not explicitly restrict the file to the owning user, verify that the destination is a regular file, reject symbolic links, or obtain separate consent for persistent credential storage. The corresponding instructions in `SKILL.md:18-19` and `SKILL.md:34` require the Agent to collect and save the key. The credential is subsequently sent in the `XBY-APIKEY` request header to `https://mcp.xiaobenyang.com/api`. Sending the key to that fixed HTTPS endpoint is part of the declared provider-mediated service design, but persistent plaintext storage is not the minimum privilege necessary to perform an individual search. Exploitation requires local access to the project directory, access through another process running under a sufficiently privileged account, ...[truncated 1238 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unbounded Dependency Versions Permit Unreviewed Future Releases

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 uses an open-ended minimum version constraint. A future installation can therefore resolve to package versions that did not exist when the Skill was reviewed. This makes builds non-reproducible and allows security, compatibility, or behavioral changes in later releases to enter the execution environment without a corresponding Skill review. The listed package names are established packages, and the audited material contains no evidence that any currently specified dependency is malicious, typosquatted, or loaded from an unsafe package index. The risk arises from unrestricted future resolution rather than from a confirmed compromise of a particular dependency. ### Attack Path 1. The Skill is installed at a later date without a lock file, constraints file, or hash verification. 2. The package resolver selects the newest versions satisfying the `>=` constraints. 3. A selected release contains a newly introduced vulnerability, malicious code following an upstream compromise, or an incompatible behavioral change. 4. The package is installed into the Skill environment. 5. Its code executes during installation, import, or normal Skill operation with the permissions of the installing or runtime account. This path depends on a compromised or vulnerable future release, or on dependency resolution from an untrusted package source; no such release is established by the audited files. ### Impact Assessment The maximum impact depends on the affected dependency and the privileges of the installation or runtime process. A compromised dependency could potentially read accessible files and environment variables, including `XBY_APIKEY`, m ...[truncated 224 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 (30)

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

The declared purpose is Wikimedia image search, yet the document references local .env credential storage, API-key management, xiaobenyang.com, and a gaokao-related project structure, with no trustworthy evidence of actual Wikimedia-specific functionality. Such identity and behavior inconsistency is a strong supply-chain risk signal: the skill may collect secrets, persist them locally, or call unrelated services while masquerading as a harmless media-search tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose is Wikimedia image search, yet the document references local .env credential storage, API-key management, xiaobenyang.com, and a gaokao-related project structure, with no trustworthy evidence of actual Wikimedia-specific functionality. Such identity and behavior inconsistency is a strong supply-chain risk signal: the skill may collect secrets, persist them locally, or call unrelated services while masquerading as a harmless media-search tool.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

Requiring an API key from an unrelated third-party site for a purported Wikimedia Commons search skill is highly suspicious because Wikimedia search normally does not require such protected credentials. This can mislead users into handing secrets to an unrelated service and routes usage through an undisclosed dependency, increasing phishing, tracking, and data-exfiltration risk.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The workflow example instructs the model to call an unrelated search_schools tool in a Wikimedia image-search skill, indicating copy-paste contamination or hidden functionality outside the stated purpose. In practice, such inconsistencies can cause agents to invoke unintended tools or endpoints, potentially disclosing user data to unrelated services or executing actions beyond expected scope.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

该文件实现的是一个通用远程MCP调用客户端:调用方可传入任意 mcp_id、tool_name 和 params,并携带 API key 发往可配置上游,而不是被限制为 Wikimedia Commons 图片搜索。这意味着一个表面上宣称“图片搜索”的技能,实际上可作为通用代理调用其他远程能力,造成能力越权、数据外传或与用户预期不符的远程操作。

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

call_tool 允许调用方指定任意工具名并原样透传参数到远程 MCP API,本质上提供了一个任意远程工具调用能力。这对“Wikimedia 图片搜索”场景明显超范围;在技能上下文中,这种隐藏的通用执行面更危险,因为使用者和平台可能只按低风险图片检索来信任和授权该技能。

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

The code manually reads the .env file and extracts XBY_APIKEY outside the normal settings framework, creating bespoke secret-handling logic that may bypass expected safeguards and auditing. Manual secret parsing also increases the chance of mishandling credentials and makes the module's behavior less transparent to users and reviewers.

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

Opening and reading .env directly as part of post-initialization performs explicit credential access and contributes to unnecessary secret exposure within application code. In a skill whose stated purpose is image search, such direct secret harvesting behavior is more dangerous because it is not obviously aligned with the advertised functionality.

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

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module persists an API key to a local .env file and updates process environment state, which introduces credential exposure risk if the file is readable by other users, committed to source control, or included in logs/backups. This is especially suspicious because the skill is described as a Wikimedia image search service, and local secret persistence is not clearly necessary for that purpose.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

The function explicitly saves the API key into a local .env file, turning a transient secret into a persistent artifact that may be exposed through source control mistakes, filesystem access, backup systems, or multi-user environments. Persisting secrets in plaintext is a substantial credential security risk.

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

The skill declares no explicit tool scope or permission boundaries despite documented capabilities involving environment access, file read/write, and network operations. In an agent setting, missing scope declarations increase the chance that a seemingly narrow image-search skill can access credentials, persist data, or reach external services without transparent user or platform controls.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

该技能在名称和完整说明中直接以中文面向用户/代理给出操作要求,且全文未说明语言可由用户选择,也未声明这是仅限中文场景的区域性技能。根据规则,强制特定语言而无用户 opt-in 或明确合理限制,属于自然语言策略违规。

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The project structure identifies the package as a gaokao-related skill rather than a Wikimedia image-search service, reinforcing that the artifact may be mislabeled or repurposed. This increases supply-chain and operator error risk because reviewers and users cannot reliably determine what code will run or what external systems it targets.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

代码中的类名、日志名和文档均表明其面向“小笨羊MCP API”通用调用,而非技能清单宣称的 Wikimedia 图片搜索服务,存在明显的功能与声明不一致。这种伪装或混淆会削弱审计与用户知情,增加在低风险外观下植入高权限远程调用能力的可能性。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code sends the caller-supplied params to an external API and includes a credential in the request headers. Although the behavior is implemented clearly, there is no confirmation prompt, print/log message for the user, or explanatory warning in this file that user/system data may be transmitted off-box.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The configuration logic is inconsistent: BaseSettings is configured with the prefix XBY_GAOKAO_, while the manual loader reads XBY_APIKEY directly from .env and the environment. This mismatch can cause operators to misunderstand which secret is used, leading to accidental exposure, failed rotations, or loading the wrong credential.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code has the ability to write credentials locally and modify environment variables at runtime, expanding the blast radius of any compromise or misuse. In the context of a Wikimedia Commons image search skill, this capability is not obviously required, so it increases suspicion and creates unnecessary secret-handling risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Writing an API key to .env without explicit user-facing notice or confirmation can silently persist secrets to disk, where they may later be exposed through repository commits, local malware, backups, or shared environments. Silent persistence is risky because users may reasonably expect a transient in-memory configuration change instead.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency is specified with only a lower bound, so future installs may resolve to different versions over time. This weakens build reproducibility and can allow a newly introduced vulnerable or incompatible release of requests to be pulled into the skill without review.

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 published advisories, but because the manifest does not pin an exact version, it is impossible to verify from this file alone whether deployments will avoid affected releases. In a network-facing image search skill, that uncertainty matters because HTTP client issues can affect credential handling, TLS behavior, or request safety depending on how the library is used.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

Using pydantic>=2.7.0 leaves the installed version unconstrained above the minimum, which makes builds non-reproducible and increases supply-chain risk. A later release could introduce a security regression or breaking behavior that gets installed automatically.

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

Pydantic has known advisories, and the unpinned version prevents confirming whether an affected release may be installed. While this file alone does not prove exploitability, the uncertainty is a real supply-chain weakness because vulnerable parser or validation behavior could be introduced during routine installs.

Content

No source excerpt is available for this finding.