Back to skill

Security audit

港澳台通行证识别OCR

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to be an API-based identity-document OCR tool, but it sends highly sensitive document images to an external service and stores the API key in plaintext without enough disclosure or safeguards.

Review this skill before installing. Use it only if you are comfortable sending travel-permit/passport-like images and extracted identity data to the Xiaobenyang API service, and avoid submitting real identity documents unless you understand that provider's privacy and retention practices. Prefer supplying the API key through a managed secret or environment variable rather than letting the skill save it to .env.

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

Warning
Location
scripts/config.py:42
Finding
API Key Persisted in a Predictable Plaintext File<![CDATA[ ## Vulnerability Details **File Location**: `scripts/config.py:42-61` **Vulnerability Type**: Plaintext credential storage with insufficient file-permission controls **Risk Level**: Medium ### Technical Analysis The `save_api_key_to_env` function stores the supplied API key directly in a predictable `.env` file: ```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 ``` The key is written without encryption and without explicitly applying restrictive permissions such as mode `0600`. For a newly created file, its effective permissions depend on the process umask. For an existing file, potentially unsafe permissions are retained. The predictable filename also increases the risk of exposure through source-control commits, backups, artifact collection, or access by another local process or account. The write is not atomic, which can additionally leave incomplete configuration data after interruption, although credential disclosure is the primary security concern. ### Attack Path 1. A user provides an API key as required by the Skill workflow. 2. The Agent calls `set_api_key`, which invokes `save_api_key_to_env`. 3. The function writes the credential as `XBY_APIKEY=<secret>` to `.env`. 4. An unauthorized local us ...[truncated 894 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer an operating-system credential store, managed secret service, or platform-provided secret injection mechanism instead of persistent plaintext storage. 2. If file persistence is unavoidable: - Create the file atomically with permissions set to `0600`. - Verify that the file is owned by the expected account. - Reject or repair group-readable and world-readable permissions. - Write through a securely created temporary file and atomically replace the destination. 3. Add `.env` to `.gitignore` and exclude it from build artifacts, diagnostic bundles, and backups where possible. 4. Obtain explicit user consent before persisting the key and provide an option to use an environment-only, nonpersistent credential. 5. Support credential deletion and rotation, and document the storage location. 6. Never include the key in logs, exception messages, telemetry, or returned API results. ]]>

other

Warning
Location
scripts/tools.py:25
Finding
Identity-Document Images Are Sent to an External Service Without an Explicit Privacy Warning<![CDATA[ ## Vulnerability Details **File Location**: `scripts/tools.py:25-43`; transmission sink at `scripts/call_api.py:47-76` **Vulnerability Type**: Undisclosed external transmission of sensitive personal data **Risk Level**: Medium ### Technical Analysis The Base64 OCR tool forwards the complete encoded identity-document image to the API client: ```python def ocr_pass_for_data_base64( dataBase64: str ) -> Dict[str, Any]: """ 识别港澳通行证、台湾通行证的通行证号码、姓名、性别、出生日期、有效期、签发地点等信息,支持MRZ机读码解析。 需要输入图片文件的BASE64编码。 Args: dataBase64: base64 encoded data of image file Returns: """ arguments = { "dataBase64": dataBase64 } return call_api("1826285519862794", "ocr_pass_for_data_base64", arguments) ``` The API client serializes the supplied parameters and transmits them to the configured external endpoint: ```python url = f"{settings.base_url}/api" mcp_id = mcp_id or settings.mcp_id api_key = get_api_key() if not api_key: raise UpstreamError("API密钥未设置,请先调用 set_api_key()") headers = { "XBY-APIKEY": api_key, "func": tool_name, "mcpid": mcp_id, "Content-Type": "application/json", } t0 = time.time() try: resp = self._session.post( url=url, headers=headers, data=json.dumps(params), timeout=settings.timeout_seconds, ) resp.raise_for_status() ``` The configured default recipient is `https://mcp.xiaobenyang.com/api`. The data can contain a complete Hong Kong, Macao, or Taiwan travel-permit image, including document number, name, sex, birth date, validity period, issuing location, photograph, and MRZ data. External transmission is consistent with the Skill's API-based architecture and is not covert code execution or hidden exfiltration. However, the reviewed documentation does not explicitly identify the data recipient at the point of collection, explain retention or deletion practices, describe secondary processing, or require informed con ...[truncated 1439 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Before submission, clearly disclose: - The exact external service receiving the image. - The categories of information transmitted. - The purpose of processing. - Applicable retention, deletion, and sharing practices. 2. Obtain explicit, informed user consent before transmitting an identity document. 3. Link to the provider's privacy policy and document whether submitted images are retained, used for model training, or shared with subprocessors. 4. Minimize transmitted information where technically possible, such as cropping unnecessary regions or supporting client-side redaction. 5. Do not log, cache, persist, or include full Base64 document data in exceptions or telemetry. 6. Establish contractual and technical controls for encryption in transit, retention limits, access control, incident notification, and deletion. 7. Provide a clear deletion mechanism and an alternative workflow for users who do not consent to third-party processing. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
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.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill description focuses on OCR/MRZ parsing, but the behavior includes reading/writing .env configuration, accessing environment variables, and managing remote API settings unrelated to the core user-facing claim. In the context of passport-like identity documents, hidden configuration and outbound connectivity materially increase privacy and exfiltration risk beyond what users would reasonably expect.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill description focuses on OCR/MRZ parsing, but the behavior includes reading/writing .env configuration, accessing environment variables, and managing remote API settings unrelated to the core user-facing claim. In the context of passport-like identity documents, hidden configuration and outbound connectivity materially increase privacy and exfiltration risk beyond what users would reasonably expect.

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
78% confidence
Finding
The code explicitly reads the .env file to extract XBY_APIKEY outside the normal settings loader, creating custom secret-handling logic that is easier to misuse and harder to audit. In a document-OCR skill, unnecessary direct credential file parsing increases the chance of secret exposure and bypasses safer centralized configuration controls.

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
78% confidence
Finding
Checking for and reading a local .env file as part of runtime logic grants the skill direct access to locally stored secrets, which expands the attack surface if the skill is repurposed or compromised. Given the sensitive OCR context, unnecessary secret-file access is more concerning because it combines identity data handling with credential handling in one component.

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.

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 writes an API key into a plaintext .env file, creating durable on-disk secret storage that may be readable by other local users, tools, backups, or accidentally committed to source control. Because the skill handles highly sensitive travel/identity document OCR, compromise of the API key could enable unauthorized use of the external service and potential exposure of document-processing workflows or associated data.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill declares no explicit tool scope or permissions despite documented capabilities to access environment variables, read/write local configuration, and make network requests. In a skill that handles identity-document OCR, this lack of scoping increases the risk of overbroad access and makes it harder to constrain misuse or unintended data flows.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill handles highly sensitive identity-document data yet provides no warning about privacy, retention, third-party transmission, or consent. Because passport/travel permit images contain personally identifiable and document-security information, omission of these disclosures can lead users to expose sensitive data without informed understanding of the risks.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
L037 的示例调用使用了 `search_schools(score='520', province='北京', category='综合')`,这是高考择校类函数,与本技能声明的港澳台通行证OCR无关。结合 L091 的项目目录名 `xiaobenyang_gaokao_skill/`,文档内容明显与当前技能意图不一致,属于文档对代码/技能用途的主动性误导。

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The base64 upload path encourages direct submission of full identity-document image contents without clearly warning that the content may be sent to an external OCR service. Base64 transport does not reduce sensitivity; it may actually obscure to users that they are transmitting the entire document image off-system.

Ssd 3

Medium
Confidence
97% confidence
Finding
The instruction to directly display raw API/OCR output risks exposing the full set of extracted identity-document fields, MRZ contents, and any extra metadata or debugging information returned by the remote service. In this context, raw output may contain more sensitive information than the user requested, creating unnecessary privacy leakage and possible downstream disclosure in logs or chat history.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This code retrieves a credential via get_api_key() and sends it in the XBY-APIKEY header during an outbound POST request. While the code logs request success/failure, it provides no user-facing warning, confirmation, or explanatory comment/docstring disclosing that credentials and request data will be sent to an external service.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
L09 的类文档字符串写的是“小笨羊高考Skill配置”,L12 的环境变量前缀也使用了“XBY_GAOKAO_”,这与当前技能清单描述的“港澳台通行证识别OCR”直接不一致。这不是单纯信息缺失,而是内联文档和配置命名表明代码可能源自另一项完全不同的技能,构成意图与代码上下文的明显背离。

Description-Behavior Mismatch

Medium
Confidence
86% confidence
Finding
An OCR skill for identity documents unexpectedly depends on remote-service configuration and API key handling, which expands the trust boundary and may cause sensitive document data to be sent to an external endpoint. In this context, hidden or poorly disclosed network dependence is risky because the skill handles high-sensitivity personal identity information.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The code can modify the local .env file and process environment at runtime, giving the skill persistence over credentials and configuration beyond what is strictly necessary for OCR. This increases the risk of unauthorized secret persistence, accidental overwrites, and durable configuration changes that survive the current session.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
Persisting an API key to .env without a user-facing warning or confirmation can store secrets on disk unexpectedly, where they may later be exposed through backups, logs, repository mistakes, or other local access. Because this skill processes identity-document data, silent credential persistence also obscures the fact that external service access is being enabled long-term.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This function sends identity-document imagery or extracted OCR input to an external API, which involves highly sensitive personal data such as names, document numbers, dates of birth, and MRZ contents. The file shows no visible consent flow, disclosure, minimization, or trust-boundary warning, so users or downstream agents may transmit regulated PII to a third party without understanding the privacy and compliance implications.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
This function transmits a base64-encoded image of a travel/identity document to an external API, effectively sending the full raw document image off-platform. Because raw document images are extremely sensitive and may contain all personal and machine-readable zones, undisclosed transmission increases privacy, regulatory, and data-handling risk if the service is untrusted, logged, retained, or breached.

Intent-Code Divergence

Low
Confidence
93% confidence
Finding
L091 将项目根目录写为 `xiaobenyang_gaokao_skill/`,而全文其余部分都在描述港澳台通行证识别OCR能力。这不是单纯信息缺失,而是将技能归属到另一类业务场景,容易误导调用方对技能真实用途和组成的理解。

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 version specifier only, so builds are not reproducible and may resolve to different requests releases over time. That uncertainty increases supply-chain risk and makes it impossible to verify whether the installed version includes fixes for known requests vulnerabilities.

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
91% confidence
Finding
requests has multiple published advisories, and because the manifest does not pin a version, there is no reliable way to determine whether the installed release is affected. In a skill that likely performs OCR-related network/API calls, a vulnerable HTTP client could expose credentials, mishandle TLS or redirects, or leak sensitive request data.

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
94% confidence
Finding
Using pydantic>=2.7.0 without pinning allows future installs to pull different releases, which weakens reproducibility and complicates vulnerability management. If a later-resolved version is vulnerable or incompatible, the application may inherit that risk without any code change.

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, and the lack of version pinning makes the actual exposure unverifiable. Because this skill processes identity-document OCR data, weaknesses in parsing or validation libraries could affect reliability or create denial-of-service conditions when handling untrusted input.

Static analysis

No suspicious patterns detected.