Back to skill

Security audit

营业执照识别OCR

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to perform business-license OCR, but it persistently stores an API key in a plaintext .env file and sends license images to a third-party API without enough privacy and scoping guidance.

Install only if you are comfortable sending business-license images and extracted fields to XiaoBenYang's API. Use a dedicated, revocable API key, avoid committing .env files, and remove or rotate the key if the workspace may be shared or archived.

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

API Key Persisted in a Plaintext Environment File

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py, lines 48-63
Vulnerability Type: Plaintext storage of sensitive credentials
Risk Level: Medium

python
        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

Technical Analysis

The supplied API key is written directly to a .env file in the current working directory without encryption or an explicit restrictive file mode. When the file is newly created, its permissions depend on the process umask. When it already exists, potentially insecure permissions are retained.

The credential may consequently be accessible to other local users or processes with read access to the working directory. The file may also be included inadvertently in source-control commits, workspace archives, backups, diagnostic bundles, or container images.

The API key is additionally copied into the process environment. This is normal for many applications, but it expands exposure to process inspection, crash reporting, and child processes in environments where those channels are not adequately isolated.

Attack Path

  1. A user supplies an API key through the skill's documented configuration workflow.
  2. set_api_key() passes the credential to save_api_key_to_env().
  3. The function stores the credential as XBY_APIKEY=<secret> in the working-directory .env file.
  4. An attacker obtains loca ...[truncated 663 chars]
Remediation
View remediation

Remediation Suggestions

  • Prefer a platform-managed secret store, operating-system credential manager, or session-only environment variable instead of writing credentials to the project directory.
  • If file persistence is unavoidable, create the file atomically with mode 0600 and verify that an existing file is not readable by group or other users.
  • Store secrets in a dedicated user configuration directory rather than the current working directory.
  • Ensure .env is excluded from source control, build artifacts, logs, backups, and support bundles.
  • Validate the supplied value and reject newline or control characters before serialization.
  • Avoid exposing secrets to unnecessary child processes and redact them from errors, telemetry, and crash reports.
  • Document credential revocation and rotation procedures for users whose .env file may have been exposed.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unbounded and Unverified Third-Party Dependencies

Content
View full analysis

Vulnerability Details

File Location: requirements.txt, lines 1-4
Vulnerability Type: Non-reproducible dependency resolution without artifact verification
Risk Level: Low

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 minimum version constraint. A fresh installation can therefore resolve to future releases that were not reviewed or tested with this project. The requirements also lack package hashes, so installers cannot verify that resolved artifacts match specifically reviewed files.

The listed package names are established dependencies, and the audited files provide no evidence that any currently resolved version is malicious. The risk is prospective: a compromised upstream release, malicious distribution artifact, or incompatible future version could be selected automatically during a later installation.

Attack Path

  1. A future dependency release or distribution artifact becomes compromised, malicious, or otherwise unsafe.
  2. A user or automated build installs the project using the open-ended constraints in requirements.txt.
  3. The package resolver selects the affected release because it satisfies the minimum-version requirement.
  4. Without pinned versions and hashes, the installation proceeds without confirming that the artifact is one reviewed by the project maintainers.
  5. Malicious package installation logic or imported runtime code executes with the privileges of the installation or skill process.

Impact Assessment

Impact depends on the permissions of the environment performing installation or running the skill. A compromised dependency could read the API key, business-license image data, and other process-accessible files; make network requests; modify user-accessible files; or execute code with the privileges of the Python process. This finding does not itself establ ...[truncated 47 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin every direct and transitive dependency to reviewed versions through a lock file or fully constrained requirements file.
  • Generate and verify cryptographic hashes for all package artifacts, using installation controls such as pip install --require-hashes.
  • Install only from explicitly approved package indexes over authenticated TLS connections.
  • Use automated dependency vulnerability scanning and review updates before modifying the lock file.
  • Build dependencies in an isolated, least-privileged environment without production credentials.
  • Retain a controlled update process so security patches can be adopted promptly without automatically accepting unreviewed future releases.
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
97% confidence
Finding

The skill description omits that it reads and writes configuration, accesses environment variables, and persists an API key via .env-style storage. Hidden secret handling and local persistence increase the security and privacy risk, especially when combined with sensitive business-license data and an external API dependency.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill description omits that it reads and writes configuration, accesses environment variables, and persists an API key via .env-style storage. Hidden secret handling and local persistence increase the security and privacy risk, especially when combined with sensitive business-license data and an external API dependency.

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

This code explicitly opens and parses the local .env file to extract XBY_APIKEY, creating custom secret-reading behavior beyond normal settings loading. In the context of an OCR skill, manually scraping credentials from local files is unnecessary and increases the risk of unauthorized or opaque secret handling.

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 existence check is part of the same manual credential-harvesting path from .env, enabling the skill to probe local secret storage and read credentials if present. While not exfiltration by itself, it is unnecessary credential access for the advertised OCR purpose and makes the component more dangerous in context.

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

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

This function is dedicated to persisting an API key into a plaintext .env file, which creates durable local secret storage that can be exposed via backups, repository inclusion, other local users, or later compromise. Because the skill's stated role is business-license OCR, this hidden credential persistence is especially out of scope and therefore more suspicious and risky.

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 no explicit tool scope or permission boundaries while the described implementation includes environment access, file read/write, and outbound network/API calls. This creates an over-privileged integration surface where a consumer may assume a simple OCR skill, but the skill can also persist secrets and transmit data externally without clear guardrails.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation references unrelated gaokao/school-search functionality in a skill that is supposed to perform business-license OCR. Such cross-domain inconsistencies are a supply-chain risk indicator because they suggest copy-paste reuse, poor review hygiene, or hidden capabilities not reflected in the skill's stated purpose.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

A tool invocation example points to school-search functionality rather than the declared OCR tools, which undermines trust in the documentation and may indicate that the model could be steered toward unintended tool usage. In a skill that handles sensitive document images, ambiguous or contradictory tool guidance increases the chance of misuse or data flow to the wrong function.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill processes business-license images and explicitly sends either image URLs or base64 image data to an external API, but it provides no prominent privacy warning, consent language, retention statement, or transmission disclosure. Business licenses contain sensitive corporate and personal data, so silent third-party transmission can cause confidentiality, compliance, and trust failures.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code performs an HTTP POST to an external endpoint and sends both the supplied params payload and an API key in headers. While it has internal logging and error handling, there is no confirmation prompt, user-facing disclosure, or warning in comments/docstrings that user or system data may be transmitted off-box.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code persists an API key to a local .env file and exposes helper functions to retrieve and mutate it, which is unrelated to a simple OCR extraction capability. Storing secrets in plaintext on disk increases the chance of credential disclosure through source packaging, logs, backups, or other local users/processes.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill can write secrets to disk and mutate process environment state via os.environ, capabilities that are not justified by the stated business-license OCR function. This expands the attack surface by allowing silent credential persistence and making secret handling less visible to users and operators.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code writes the API key to .env without any user-facing disclosure, consent, or warning that the credential will be stored in plaintext. Silent persistence of secrets is dangerous because users may assume the key is used ephemerally while it actually remains on disk for later retrieval or leakage.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This function sends a business license image URL to an external API for OCR, which can disclose sensitive business identity and registration information to a third party. In a skill handling official documents, failing to provide an explicit user-facing disclosure/consent mechanism creates a real privacy and data-governance risk even if the transmission is expected for functionality.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This variant transmits the full base64-encoded business license image directly to an external API, exposing potentially sensitive corporate and personal information contained in the document. Because base64 content usually contains the entire document payload, the privacy impact is at least as significant as the URL-based version and warrants explicit disclosure and consent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
73% confidence
Finding

All user-facing instructions and descriptions are written exclusively in Chinese, and the skill does not state that language support is limited by design or provide any opt-in choice for language or locale. Under the stated policy, forcing a specific language without user choice can be a natural-language policy issue unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

项目结构部分将根目录写成 xiaobenyang_gaokao_skill/,这与当前技能名“营业执照识别OCR”及其功能说明相冲突。该类文档残留会误导维护者和代理理解该技能的真实意图与代码归属。

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 range (requests>=2.31.0) instead of pinning an exact version, which makes builds non-reproducible and can silently pull in vulnerable or incompatible releases over time. In an OCR skill that likely processes business-license data and may make outbound HTTP requests, dependency drift increases supply-chain risk even though the manifest alone does not prove exploitation.

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

The manifest references requests without an exact version while the package has multiple known advisories, so it is impossible to verify from this file whether the installed release is affected. Given requests is often used for outbound network access, an affected version could lead to credential leakage or TLS/request-handling weaknesses depending on actual usage.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

pydantic>=2.7.0 is unpinned, so installations may resolve to different future versions with unknown security posture or breaking behavior. Because this package is commonly used to validate structured input and configuration, a vulnerable version could weaken input handling or expose the skill to parser-related flaws.

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

The file does not pin pydantic, and the package has known advisories, so the security state of deployed environments cannot be verified from the manifest. Because pydantic may parse and validate attacker-controlled data, unresolved version ambiguity can matter if a vulnerable parser or regex-related release is installed.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

pydantic-settings>=2.2.0 is not pinned, leaving runtime environments free to install different versions with varying security characteristics. Since settings libraries often touch environment variables, secrets, and file-based configuration, version ambiguity creates avoidable supply-chain and configuration-handling risk.

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