Back to skill

Security audit

PDF阅读服务

Security checks for vulnerabilities and agentic risk

Overview

This PDF skill depends on a remote Xiaobenyang service and saves an API key locally, but its scoping and documentation are inconsistent enough to require review before installation.

Install only if you are comfortable sending PDF-related paths, URLs, and search parameters to the Xiaobenyang remote API and storing the XBY_APIKEY in a local plaintext .env file. Review the provider, rotate the key if exposed, keep .env out of version control, and prefer a secure secret mechanism before using this with sensitive PDFs.

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

Plaintext API Key Persistence Without Input Validation or Permission Hardening

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py, lines 45-67
Vulnerability Type: Plaintext credential storage and environment-file injection
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 persistently writes the supplied API key to a plaintext .env file in the process's current working directory. It does not create or enforce restrictive file permissions, use a protected credential store, or perform an atomic secure write. A newly created file inherits permissions from the process umask, while an existing file retains any previously permissive mode.

The API key is interpolated directly into the environment-file content without rejecting carriage returns or newline characters. Consequently, an attacker who can control the value passed to set_api_key() can insert additional environment-file records. For example, a value containing valid-key\nADDITIONAL_SETTING=attacker-value would be persisted as multiple lines.

The Skill documentation explicitly directs the agent to collect a key from the user and call scripts.config.set_api_key(), making t ...[truncated 1648 chars]

Remediation
View remediation

Remediation Suggestions

  1. Prefer obtaining the API key exclusively from the process environment or a platform credential manager rather than persisting it in the project directory.
  2. If local persistence is required, store the credential in an operating-system keychain or dedicated secret-management service.
  3. Reject values containing carriage returns, line feeds, NUL bytes, or other control characters before writing:
    python
    if any(character in api_key for character in ("\r", "\n", "\0")):
        return False
    
  4. Create secret files with mode 0600 and verify or correct permissions on existing files before use.
  5. Write updates atomically through a securely created temporary file, set restrictive permissions, flush the content, and replace the destination.
  6. Store the file in a predictable per-user configuration directory rather than the current working directory.
  7. Ensure .env is excluded from source control, build artifacts, diagnostic bundles, and backups that are not authorized to contain secrets.
  8. Document that the credential is sent in the XBY-APIKEY header to the configured remote API and provide a supported mechanism for revocation and rotation.
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 (32)

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

The documentation says this is a PDF service, but it also instructs reading/writing a local .env file, modifying XBY_APIKEY, and configuring an unrelated external service. This discrepancy creates a deceptive trust boundary: users may provide sensitive files or secrets believing they are using a focused PDF tool when the skill actually persists credentials and interacts with a different backend.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documentation says this is a PDF service, but it also instructs reading/writing a local .env file, modifying XBY_APIKEY, and configuring an unrelated external service. This discrepancy creates a deceptive trust boundary: users may provide sensitive files or secrets believing they are using a focused PDF tool when the skill actually persists credentials and interacts with a different backend.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The section presents the skill as a PDF analysis service, but the workflow requires an API key for an unrelated external service and routes all actions through generic remote calls. This inconsistency is dangerous because it can trick operators or users into authorizing data flows and secret storage that are unrelated to the advertised PDF 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",
    )

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code explicitly reads sensitive credentials from .env and process environment variables, giving the skill credential access capabilities that do not match a simple PDF reader's expected behavior. In a plugin or MCP setting, this can expose secrets from the local environment and creates a path for unauthorized use of credentials if other parts of the skill are compromised or repurposed.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

The code forcefully reads a specific API key from a local .env file, bypassing normal least-privilege expectations for a PDF-reading skill and granting access to locally stored secrets. In this context, undeclared secret-reading capability is dangerous because the skill can inspect or depend on credentials unrelated to PDF processing.

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

Opening and reading the .env file directly gives this skill file-level access to local secret material in plaintext. In an agent/plugin environment, such capability is risky when not clearly necessary for the advertised PDF functionality, because it can facilitate credential exposure or misuse.

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

This module implements persistence and retrieval of an external service API key by writing it to and reading it from a local .env file, which is unrelated to the stated PDF-reading functionality. In an agent skill context, adding credential management expands the attack surface: secrets may be stored insecurely, overwritten, or later abused by unrelated code paths or copied artifacts.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The function persists an API key into a local .env file, creating plaintext at-rest storage of credentials and increasing the risk of accidental disclosure through source control, logs, backups, or local compromise. This is especially concerning because secret persistence is outside the expected behavior of a PDF reading service.

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 capabilities to access environment variables, read/write local files, and use the network, but it does not declare any explicit tool scope or permission boundaries. In a skill that also instructs persistence of an API key and accepts local paths or URLs, this lack of scoping increases the risk of unintended secret handling, overbroad file access, and unnoticed external transmission.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The workflow example references an unrelated school-search function instead of the advertised PDF tools, indicating copy-paste or template contamination from another skill. Such inconsistencies undermine trust and can cause an agent to invoke the wrong tools or route user data to unintended services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill accepts local file paths and remote URLs for PDFs and appears to rely on an external API, yet it does not warn that document locations or contents may be transmitted off-host. For sensitive PDFs, this omission can lead to unintentional disclosure of confidential information, especially if users assume local-only processing.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The project structure names an unrelated gaokao skill even though the skill is presented as a PDF service. This mismatch strongly suggests repurposed or mislabeled code, which increases the chance of hidden data flows, misconfiguration, and user misunderstanding about where secrets and content are sent.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

A PDF reading and analysis service would typically operate on provided files locally; this code creates an HTTP session and posts requests to a remote API endpoint using an API key. Because the manifest does not mention remote API brokering or cloud-backed processing, this network capability is not clearly justified by the stated purpose alone.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The client mounts both "http://" and "https://" adapters and builds requests from a configurable base URL without enforcing TLS, while sending the API key in the XBY-APIKEY header. If settings.base_url is configured as plain HTTP, credentials and possibly PDF-derived sensitive content can be intercepted or modified by an on-path attacker.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest describes a PDF-reading MCP server with metadata extraction, page-range reading, and keyword search. This file instead implements a reusable client that sends arbitrary tool invocations and parameters to an external upstream service via HTTP, which is broader than the stated local PDF-processing behavior and not clearly limited to PDF operations.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

当前技能清单名称和描述都表明这是一个 PDF 阅读服务,但 Settings 类的文档字符串却写成“高考Skill配置”。这不是简单遗漏,而是直接指向另一种完全不同的技能意图,暗示代码来源或用途与当前技能声明不一致。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Persisting an API key to .env without explicit user warning or confirmation creates a secret-handling risk because users may not realize a credential is being stored on disk. Local files can be accidentally committed, included in backups, or read by other processes with filesystem access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The skill's user-facing instructions are predominantly in Chinese and present mandatory operational requirements, but the document does not offer users a language option or state that the skill is intentionally limited to a Chinese-speaking audience. This can violate language/locale policy where user opt-in or justification is required.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency is specified with a lower bound only (requests>=2.31.0), which allows installation of any future release and makes builds non-reproducible. This increases supply-chain risk and makes it hard to determine whether a deployed version contains known vulnerabilities or breaking security-relevant 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
92% confidence
Finding

requests has known advisories, but because the manifest does not pin an exact version, it is impossible to verify whether the installed release is affected or already patched. In practice this is a dependency hygiene vulnerability: the project cannot demonstrate a safe resolved version and may unintentionally install an affected one.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

pydantic>=2.7.0 is unpinned, so environments may resolve to different versions over time. That weakens reproducibility and can silently introduce vulnerable or incompatible releases into the PDF service.

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

pydantic has published security advisories, and the loose version constraint prevents determining whether deployments are vulnerable. This uncertainty is a real supply-chain risk because the service may resolve to an affected version depending on installation time and environment.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.