Back to skill

Security audit

image-reader

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real image/OCR helper, but it can upload any readable local file path to an external model API without strong file validation, size limits, or an explicit consent step.

Install only if you are comfortable sending selected images or screenshots to the configured Volcengine/OpenAI-compatible API. Avoid sensitive documents, credentials, private keys, or internal screenshots unless your environment explicitly approves that sharing, and prefer a wrapper that restricts input to confirmed image files with size and type checks.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
image_reader.py:31
Finding
Unrestricted Local File Upload to an External API<![CDATA[ ## Vulnerability Details **File Location**: `image_reader.py:31-34`, `image_reader.py:51`, `image_reader.py:66`, `image_reader.py:74-80`, and `image_reader.py:98-103` **Vulnerability Type**: Unrestricted local file access and external transmission **Risk Level**: Medium ### Vulnerable Code ```python def encode_image(image_path: str) -> str: """将图片编码为 base64""" with open(image_path, "rb") as image_file: return base64.b64encode(image_file.read()).decode('utf-8') ``` ```python # 编码图片 base64_image = encode_image(image_path) ``` ```python { "type": "image_url", "image_url": { "url": f"data:image/png;base64,{base64_image}" } } ``` ```python response = client.chat.completions.create( model=model, messages=messages, temperature=0.7, max_tokens=64000 ) ``` ```python parser.add_argument('image_path', help='图片文件路径') parser.add_argument('--prompt', '-p', help='额外的分析提示', default=None) args = parser.parse_args() # 检查图片文件是否存在 if not os.path.exists(args.image_path): print(f"错误: 图片文件不存在: {args.image_path}") sys.exit(1) ``` ### Technical Analysis The program accepts an arbitrary filesystem path and checks only whether that path exists. It does not verify that the target is a regular file, that it is located in an approved directory, or that its content is a supported image format. The complete file is then read into memory, Base64-encoded, labeled as `image/png` regardless of its real type, and transmitted to the externally configured API endpoint. Base64 encoding is a legitimate and documented transport mechanism for multimodal API requests; it is not inherently a covert exfiltration technique. The security issue is the absence of controls around which local files may be encoded and uploaded. The process cannot read files beyond its operating-system permissions. Nevertheless, when invoked by an agent running with broader access than the requesting user, this behavior can cross a least-privilege bo ...[truncated 2033 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Resolve the supplied path with `Path.resolve()` and require it to remain inside an explicitly approved image-upload directory. 2. Require the target to be a regular file using `Path.is_file()` and reject symbolic links, device files, named pipes, sockets, and directories. 3. Validate the content using trusted image decoding or file-signature inspection rather than relying only on the filename extension. 4. Permit only explicitly supported image formats and derive the data URI MIME type from validated content rather than always using `image/png`. 5. Enforce a conservative maximum input size before reading the file. Read in a controlled manner rather than loading an unbounded file into memory. 6. In agent-driven use, require explicit user confirmation that identifies both the selected file and the external destination before uploading. 7. Run the Skill under a dedicated, least-privileged account with access only to approved image directories. 8. Clearly disclose the external endpoint and applicable data-retention policy at invocation time. 9. Prefer direct attachment objects or bounded streaming mechanisms if supported by the API client. ]]>

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding
Unpinned Third-Party Dependencies Without Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-2` and `README.md:14-16` **Vulnerability Type**: Uncontrolled dependency resolution and missing package integrity controls **Risk Level**: Low ### Vulnerable Code ```text openai>=1.0.0 pyyaml>=6.0 ``` The documented installation command is: ```bash pip install -r requirements.txt ``` ### Technical Analysis Both dependencies use open-ended minimum-version constraints. As a result, installations performed at different times may resolve to different, unreviewed package releases. The project supplies neither a lockfile nor cryptographic hashes for package artifacts. No evidence was found that the currently named packages are malicious, misspelled, or retrieved from a custom unsafe source. The issue is that future dependency versions are implicitly trusted without reproducible resolution or integrity verification. A compromised upstream release, account takeover, or incompatible update could therefore introduce code that executes during installation or when the Skill imports and uses the package. ### Attack Path 1. A user follows the README and runs `pip install -r requirements.txt`. 2. The package resolver queries the configured package index and selects any available release satisfying the broad minimum-version constraints. 3. A future compromised, malicious, or unexpectedly incompatible release may be selected because no reviewed upper bound, lockfile, or artifact hash is enforced. 4. Package installation code or imported runtime code executes with the privileges of the installing or invoking user. 5. A malicious dependency could access local data, alter files, intercept the API key or uploaded images, or perform arbitrary actions allowed to that user account. This path is conditional on compromise or malicious publication in the dependency supply chain; the audited repository itself contains no evidence that such a compromise has occurred. ### Impact Assessment If a resolved de ...[truncated 577 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin each dependency to a specifically reviewed version instead of using open-ended minimum constraints. 2. Generate and commit a lockfile containing exact transitive dependency versions. 3. Use hash verification, such as pip's `--require-hashes`, to ensure downloaded artifacts match reviewed package files. 4. Install only from explicitly approved package indexes over TLS and prevent fallback to untrusted indexes. 5. Automate vulnerability and provenance scanning for direct and transitive dependencies. 6. Review dependency updates in controlled pull requests and test them before deployment. 7. Use an isolated virtual environment and avoid installing the Skill or its dependencies with administrator or root privileges. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (11)

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The README presents the skill as local image analysis but does not clearly disclose that submitted images are sent to a third-party multimodal API provider. This can cause users to unknowingly transmit sensitive screenshots, documents, or personal data off-device, which is especially risky for an image/OCR skill because users commonly provide confidential visual content.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill declares no explicit tool scope even though it is expected to read local image files before sending them for analysis. Missing scope metadata can cause the platform or reviewer to underestimate what the skill can access, increasing the chance of unintended file access or overly broad invocation behavior. In an image-analysis skill, file access is contextually expected, but it still should be declared so users and orchestration layers can enforce least privilege.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill description highlights OCR and image understanding but does not clearly warn that images are sent off-device to a third-party remote API. This omission is dangerous because users may provide screenshots containing credentials, personal data, financial records, or internal documents under the assumption of local processing, leading to confidentiality and compliance risks.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The invocation phrases are extremely generic, such as 'Analyze this image' and 'Describe this screenshot,' which can overlap with ordinary conversation and cause accidental or overly eager skill triggering. Because this skill transmits image contents to a remote multimodal API, unintended invocation could expose sensitive screenshots, documents, or personal photos without sufficiently explicit user intent.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The system prompt explicitly instructs the skill to always reply in Chinese. This is a natural-language locale policy concern because it imposes a specific language regardless of the user's preferred language and provides no opt-in or choice mechanism.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
All user-facing strings, including the description, prompts, and error/help text, are hard-coded in Chinese. This imposes a specific language/locale on users without any visible option to select another language or an explanation that the tool is intended only for a Chinese-language context.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The code sends the full image content to a remote multimodal API by base64-embedding it into the request, but the user-facing interface gives no explicit disclosure, consent step, or privacy warning. Because screenshots and images commonly contain sensitive data such as credentials, personal information, or internal documents, this creates a real data-exposure risk, especially in an agent-skill context where users may assume processing is local.

Missing User Warnings

Low
Confidence
82% confidence
Finding
The configuration section indicates use of an API key, including a built-in default, but does not warn users about credential sensitivity or the security implications of invoking an external service. This increases the chance of accidental key exposure, misuse of embedded credentials, or unsafe deployment practices, though the README alone does not directly leak a secret.

Unpinned Dependencies

Low
Category
Supply Chain
Content
openai>=1.0.0
pyyaml>=6.0
Confidence
94% confidence
Finding
The dependency is specified with only a lower bound, which permits installation of any future major or minor version. This weakens reproducibility and can unexpectedly introduce vulnerable or breaking releases into the environment through supply-chain drift.

Unpinned Dependencies

Low
Category
Supply Chain
Content
openai>=1.0.0
pyyaml>=6.0
Confidence
97% confidence
Finding
The PyYAML dependency is not pinned, so deployment may resolve to different versions across environments, including versions with known security advisories. Because YAML libraries have a history of unsafe parsing issues, leaving the version unconstrained increases supply-chain and exposure risk.

Unverifiable Dependency: pyyaml has 8 known advisory(ies) (CVE-2019-20477 (Deserialization of Untrusted Data in PyYAML); CVE-2020-1747 (Improper Input Validation in PyYAML); CVE-2020-14343 (Improper Input Validation in PyYAML) +5 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding
PyYAML has multiple historical CVEs involving unsafe deserialization and input handling, and the manifest does not pin a version, so there is no assurance that affected releases are excluded. In a skill that may process external content or configuration, this uncertainty meaningfully raises the chance of pulling a vulnerable package.

Static analysis

No suspicious patterns detected.