Back to skill

Security audit

论文检索与解析工具

Security checks for vulnerabilities and agentic risk

Overview

This paper-search skill mostly routes requests to an external Xiaobenyang MCP service, but it also persists API keys in a local .env file and contains mismatched gaokao-related code and documentation.

Review before installing. Use only if you trust the Xiaobenyang service and are comfortable sending paper queries and identifiers to it. Do not provide a sensitive or broad API key unless you accept that the skill may store it in plaintext in .env; prefer a limited key and remove or rotate it after use.

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 Plaintext Without File Permission Hardening<![CDATA[ ## Vulnerability Details **File Location**: `scripts/config.py:46-65` **Vulnerability Type**: Plaintext sensitive-data storage **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 the user-provided API key as plaintext in a `.env` file located in the process's current working directory. The file is created using `Path.write_text()` without explicitly enforcing restrictive filesystem permissions, validating file ownership, checking whether the target is a symbolic link, or confirming that the working directory is private. The resulting permissions depend on the process umask and the state of any pre-existing `.env` file. In a shared or incorrectly configured environment, other local accounts or processes may be able to read the credential. Because the file is placed in the working directory, it may also be included inadvertently in source-control commits, archives, backups, or diagnostic bundles. The code additionally places the key in the process environment. Child processes created afterward may inherit it, increasing the credential's exposure scope. ### Attack Path 1. A user provides an Xiaobenyang API key as requi ...[truncated 1149 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer session-only credential handling or an operating-system credential manager instead of plaintext persistence. 2. Obtain explicit user consent before persisting an API key. 3. If file storage is unavoidable, create the file atomically with mode `0600` and verify the final permissions. 4. Validate that `.env` is a regular file owned by the expected user; reject symbolic links and unexpected owners. 5. Resolve storage against a private, explicitly configured directory rather than the ambient working directory. 6. Add `.env` to `.gitignore` and exclude it from archives, logs, backups, and diagnostic output. 7. Avoid exporting the key into the process environment unless required, and prevent unnecessary inheritance by child processes. 8. Document credential rotation and revocation procedures in case the file is exposed. ]]>

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding
Unbounded Dependency Versions Permit Unreviewed Package Updates<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-4` **Vulnerability Type**: Non-reproducible and insufficiently constrained dependencies **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 an open-ended lower-bound constraint. A future installation can therefore resolve to package releases that did not exist and were not reviewed when the Skill was audited. This makes installations non-reproducible and allows dependency behavior to change without corresponding changes to the project. No typosquatted package, malicious package, or unsafe package index was identified in the audited files. The risk is that a future compromised, malicious, or incompatible release satisfying these constraints could be selected automatically. Python packages may execute code during installation, import, or ordinary runtime, so compromise of an allowed dependency can affect the Skill process. ### Attack Path 1. The project is installed at a later date without a lock file or hash verification. 2. The package resolver selects newer releases satisfying the `>=` constraints. 3. One selected release has been compromised, contains malicious behavior, or introduces a security regression. 4. The dependency's code executes during installation, import, or runtime. 5. That code receives the permissions of the installer or Skill process and may access files, environment variables, network resources, and the API key available to that process. This attack path is conditional on compromise or unsafe behavior in a future permitted release; no currently malicious dependency was confirmed by the reviewed source. ### Impact Assessment A compromised dependency could execute arbitrary Python code with the privileges of the account installing or running the Skill. Potential impact includes reading the persisted API key, modifying project files, maki ...[truncated 207 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin each dependency to a reviewed exact version. 2. Generate and commit a reproducible lock file appropriate for the deployment workflow. 3. Require package hashes, such as through a hash-locked requirements file. 4. Install packages only from an explicitly trusted package index over TLS. 5. Review dependency updates through automated vulnerability scanning and controlled pull requests. 6. Separate dependency resolution from production installation so production environments install only previously reviewed artifacts. 7. Rebuild pinned dependencies regularly to receive security fixes without accepting arbitrary releases automatically. ]]>
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 (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
A second mismatch is the apparent inclusion of local .env persistence, API key management, unrelated base_url/mcp_id configuration, and even traces of a gaokao-oriented project structure. Such inconsistencies strongly suggest copy-paste drift or undeclared behavior, which can hide sensitive data handling and make the skill operate outside its stated academic-paper purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
A second mismatch is the apparent inclusion of local .env persistence, API key management, unrelated base_url/mcp_id configuration, and even traces of a gaokao-oriented project structure. Such inconsistencies strongly suggest copy-paste drift or undeclared behavior, which can hide sensitive data handling and make the skill operate outside its stated academic-paper purpose.

Context-Inappropriate Capability

High
Confidence
95% confidence
Finding
The call_tool method accepts arbitrary tool_name and params and places them directly into an authenticated upstream request, effectively exposing a generic remote tool invocation primitive. In a skill advertised for paper retrieval/parsing, this broader capability increases the risk of unintended external actions, data exfiltration, or abuse if untrusted input can influence mcp_id, tool_name, or params.

Credential Access

High
Category
Privilege Escalation
Content
model_config = SettingsConfigDict(
        env_prefix="XBY_GAOKAO_",
        env_file=".env",
        env_file_encoding="utf-8",
        extra="ignore",
    )
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
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")
Confidence
87% confidence
Finding
This code explicitly opens and parses .env to extract XBY_APIKEY, bypassing normal settings abstraction and directly handling credential material. In the context of a paper-retrieval skill, this unnecessary secret-reading behavior broadens access to local credentials and is especially suspicious because it targets an unrelated service.

Credential Access

High
Category
Privilege Escalation
Content
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():
Confidence
87% confidence
Finding
The existence check and subsequent read of .env are part of direct credential-access logic, which is unnecessary for the advertised functionality and increases exposure to local secrets. Because the targeted key is unrelated to the stated skill purpose, this behavior is more dangerous than routine configuration loading.

Credential Access

High
Category
Privilege Escalation
Content
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
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill claims to be an arXiv paper search/parser, but this code adds unrelated credential-management behavior for an XBY API key and persists it locally. That mismatch is dangerous because it creates an unnecessary secret-handling surface and can mislead users into granting or storing credentials unrelated to the advertised functionality.

Credential Access

High
Category
Privilege Escalation
Content
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()
Confidence
94% confidence
Finding
This function is dedicated to persisting an API key into .env, creating durable local storage of a secret for an unrelated external service. Persisting credentials in a plaintext project file is high risk because it can be leaked via source control, filesystem access, backups, or accidental disclosure, and the skill context makes this behavior unjustified.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill declares no explicit tool scope or permission boundaries even though it appears to rely on environment access, local file read/write, and network operations. In an agent setting, missing scope declarations increase the chance of over-privileged execution, unclear review boundaries, and abuse of capabilities such as persistent config writes or unvetted outbound requests.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill instructs the agent to collect a user API key and persist it via local configuration without warning the user that the secret will be stored. This is risky because users may assume ephemeral use, while local persistence increases the chance of accidental disclosure through files, logs, backups, or access by other tools/processes.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The workflow example instructs the agent to call a gaokao school-search function instead of a paper-retrieval function. In practice, this kind of instruction mismatch can route user prompts into the wrong toolchain, causing unintended external requests, data leakage to unrelated services, or execution of code paths that reviewers did not expect for this skill.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The implementation does not appear limited to arXiv search or PDF parsing as described in the skill metadata; instead, it is a generic wrapper that forwards requests to an external MCP API with caller-controlled tool names and parameters. This creates a capability/description mismatch that can mislead users and reviewers about what data is sent off-platform and what external actions the skill can trigger.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
This code sends the supplied params to an external API endpoint and includes an API credential in request headers. While the code logs success and error outcomes, it does not provide any user-facing warning, confirmation, or explanatory comment/docstring that this operation transmits user/system data off-host.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The class comment, env prefix, and identifiers reference a different product/domain ('高考/XBY') than the declared paper-retrieval skill. This strong intent mismatch is a supply-chain red flag because reused or transplanted config code may introduce hidden external dependencies, secret flows, or behavior users would not expect from the advertised tool.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
A paper-search skill should not normally need to modify local configuration files, yet this code can rewrite .env and persist credentials. Unnecessary file-write capability increases the blast radius of compromise, may overwrite existing secrets, and creates persistence of sensitive data beyond the current session.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The code writes an API key to .env silently, without any disclosure that the credential will be stored on disk. This is dangerous because users may believe they are providing a transient token, while the skill creates durable local secret storage that can later be exposed through backups, logs, repository commits, or other local access.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The parameter description states `搜索英文关键词`, which imposes an English-language requirement. This is a natural-language locale/language constraint, and the file does not present it as an optional preference, offer translation/help, or justify it as a documented limitation with user opt-in.

Intent-Code Divergence

Low
Confidence
93% confidence
Finding
项目结构部分将根目录写为 `xiaobenyang_gaokao_skill/`,这与当前技能的论文检索与解析用途不一致。虽然这不直接证明代码行为异常,但属于文档层面对技能身份和意图的明显矛盾,可能误导调用者或维护者。

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
Confidence
95% confidence
Finding
The dependency uses a lower-bound specifier (requests>=2.31.0) rather than a pinned or tightly constrained version, which makes builds non-reproducible and can cause an environment to resolve to an unintended future release. In a security context, this also makes it hard to verify whether a deployed version includes fixes for known advisories or introduces new vulnerable behavior.

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
89% confidence
Finding
The manifest does not pin the requests version, and requests has multiple known advisories across releases. Because the effective installed version is not fixed, the project cannot demonstrate that it avoids affected versions, leaving potential exposure to known dependency flaws.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
Confidence
95% confidence
Finding
The dependency pydantic>=2.7.0 is unpinned, so installations may resolve differently over time and across environments. This weakens supply-chain control and makes it difficult to confirm that only reviewed, non-vulnerable versions are installed.

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
87% confidence
Finding
Pydantic has known advisories in some versions, but this manifest only sets a minimum version and does not prove that deployed environments will use a safe release. The main risk is unverifiable exposure rather than evidence of an active vulnerable version in this file alone.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
Confidence
95% confidence
Finding
Using pydantic-settings>=2.2.0 allows arbitrary newer versions to be installed, reducing reproducibility and assurance about the security posture of the runtime environment. This is a common supply-chain hygiene issue even when no specific exploit is present in the file itself.

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
84% confidence
Finding
Because pydantic-settings is not pinned, it is impossible to confirm from this manifest whether installations will avoid advisory-affected versions. This creates avoidable supply-chain uncertainty, especially for configuration-handling libraries that may touch secrets or filesystem paths.

Static analysis

No suspicious patterns detected.