Back to skill

Security audit

Image To Code

Security checks for vulnerabilities and agentic risk

Overview

The skill performs image-to-code conversion, but it defaults to sending full images to Baidu OCR using embedded shared credentials without clear enough controls or disclosure.

Review this skill before installing. Do not use the default path on confidential screenshots, personal data, credentials, source code, or regulated documents unless third-party Baidu OCR processing is approved. Prefer a local-only OCR configuration, replace embedded credentials with your own securely supplied keys, and pin dependencies before 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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
image_to_code.py:42
Finding
Hardcoded Baidu OCR Credentials Exposed in Source Code<![CDATA[ ## Vulnerability Details **File Location**: `image_to_code.py`, lines 42-50 **Vulnerability Type**: Hardcoded API credentials **Risk Level**: High ### Vulnerable Code ```python self.baidu_api_key = None self.baidu_secret_key = None self.baidu_access_token = None # Baidu OCR configuration if self.use_baidu_ocr: self.baidu_api_key = "4LceeJ8wBDSqa3SqDHmgXuk1" self.baidu_secret_key = "nIulIWxqaUtY5XyfexSvP4OL8ZBk0krR" self._init_baidu_ocr() ``` The embedded credentials are subsequently submitted to the Baidu OAuth endpoint: ```python url = "https://aip.baidubce.com/oauth/2.0/token" params = { "grant_type": "client_credentials", "client_id": self.baidu_api_key, "client_secret": self.baidu_secret_key } response = requests.post(url, params=params, timeout=10) result = response.json() ``` ### Technical Analysis API credentials are stored directly in distributable source code. Any user who can download, inspect, or otherwise access the Skill package can recover the key and secret without authorization. Hardcoded secrets cannot be isolated per installation and cannot be rotated without modifying or redistributing the application. Because the OAuth flow uses the credentials to acquire an access token, possession of the source values may enable third parties to authenticate against the associated Baidu account within the permissions granted to that application. The documentation reinforces that the credentials are intentionally distributed by stating that the API key is built in. Although this supports convenient configuration, it violates secure secret-management practices and is not necessary for image conversion. ### Attack Path 1. An attacker obtains a copy of the Skill package. 2. The attacker reads `image_to_code.py` and extracts the API key and secret. 3. The attacker submits the credentials to the configured Baidu OAuth token endpoint. 4. If the credentials remain active, Baidu returns an access token. 5. The attacker ...[truncated 814 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Revoke and rotate the exposed Baidu credentials immediately. 2. Remove all credentials from source code, documentation, examples, test fixtures, and version history. 3. Require users to supply their own credentials through environment variables or a secret manager, for example: ```python import os self.baidu_api_key = os.environ.get("BAIDU_OCR_API_KEY") self.baidu_secret_key = os.environ.get("BAIDU_OCR_SECRET_KEY") ``` 4. Refuse to enable Baidu OCR when either credential is absent; do not silently substitute shared credentials. 5. Ensure error messages never print credentials, tokens, or complete authentication responses. 6. Apply least-privilege permissions and quota limits to the replacement application credentials. 7. Add automated secret scanning to the development and release process. 8. Review repository history and released artifacts because removing a secret from the latest file does not invalidate previously published copies. ]]>

other

Error
Location
image_to_code.py:100
Finding
Complete Input Images Are Transmitted to an External OCR Service by Default<![CDATA[ ## Vulnerability Details **File Location**: `image_to_code.py`, lines 31-50 and 100-163 **Vulnerability Type**: Unconsented external data transmission **Risk Level**: High ### Vulnerable Code Baidu OCR is enabled by default and initialized during object construction: ```python def __init__(self, ocr_lang='ch', use_vision_ai=False, use_baidu_ocr=True): """ Initialize converter Args: ocr_lang: OCR language ('ch' Chinese, 'en' English) use_vision_ai: whether to use visual AI for formula recognition use_baidu_ocr: whether to use Baidu OCR (preferred, high accuracy) """ self.ocr_lang = ocr_lang self.use_vision_ai = use_vision_ai self.use_baidu_ocr = use_baidu_ocr self.baidu_api_key = None self.baidu_secret_key = None self.baidu_access_token = None # Baidu OCR configuration if self.use_baidu_ocr: self.baidu_api_key = "4LceeJ8wBDSqa3SqDHmgXuk1" self.baidu_secret_key = "nIulIWxqaUtY5XyfexSvP4OL8ZBk0krR" self._init_baidu_ocr() ``` The entire image is JPEG-encoded, Base64-encoded, and submitted to Baidu: ```python def _ocr_with_baidu(self, image: np.ndarray) -> List[str]: """ Use Baidu OCR to recognize an image """ if not self.baidu_access_token: return [] try: # Convert to JPG format _, buffer = cv2.imencode('.jpg', image) img_base64 = base64.b64encode(buffer).decode('utf-8') # Call Baidu OCR API url = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic" url += f"?access_token={self.baidu_access_token}" headers = { "Content-Type": "application/x-www-form-urlencoded" } data = { "image": img_base64, "detect_direction": "true", "detect_language": "true" } response = requests.post(url, headers=headers, data=data, timeout=30) result = response.json() if "error_code" in result ...[truncated 2945 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make offline OCR the default processing mode. 2. Require explicit cloud opt-in, such as: ```bash python3 image_to_code.py input.png --baidu-ocr ``` 3. Add an explicit `--offline` option that blocks all network access and fails closed if local OCR is unavailable. 4. Display a clear warning and request confirmation before the first external upload. 5. Document: - The exact destination service and domain. - What data is uploaded. - Whether metadata is included. - Provider retention and training policies. - Applicable data residency and privacy implications. 6. Require user-specific credentials rather than embedded shared credentials. 7. Consider client-side redaction or region-based upload so that only necessary OCR regions are transmitted. 8. Provide policy controls allowing administrators to disable cloud OCR entirely. 9. Add tests that verify offline mode performs no DNS resolution or outbound network requests. 10. Reconcile `SKILL.md`, `README.md`, `README_BAIDU.md`, metadata, and CLI help so default network behavior is disclosed consistently. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Unpinned Dependencies Permit Non-Reproducible and Unsafe Package Installation<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt`, lines 1-5; `install.sh`, lines 17-19 **Vulnerability Type**: Unpinned third-party dependency installation **Risk Level**: Medium ### Vulnerable Code `requirements.txt` permits any future version satisfying a minimum constraint: ```text paddlepaddle>=2.5.0 paddleocr>=2.7.0 opencv-python>=4.8.0 numpy>=1.24.0 Pillow>=10.0.0 ``` The installation script installs those packages directly from the active pip configuration: ```bash # Install dependencies echo "📦 Installing dependencies..." pip3 install -r requirements.txt ``` The runtime also imports `requests`: ```python import requests ``` However, `requests` is not declared in `requirements.txt`, despite being listed separately in `metadata.json`. ### Technical Analysis Minimum-only version constraints do not identify a reviewed build. Running the installer at different times can install different package versions, including future major releases if their version numbers satisfy the constraint. Python packages can execute code during installation or when imported. If a permitted future dependency version, transitive dependency, or configured package index is compromised, the installation process can execute attacker-controlled code with the privileges of the user running `pip3`. No hashes are provided, so package artifacts are not cryptographically constrained to reviewed distributions. The installer also does not create an isolated virtual environment or enforce a trusted package index. The undeclared `requests` dependency makes behavior dependent on the ambient Python environment. On some systems the Skill fails; on others it silently uses whatever `requests` version happens to be installed. ### Attack Path 1. An attacker compromises a future release of one of the permitted packages, a transitive dependency, or a package source used by the victim. 2. The malicious release retains a version number satisfying the `>=` constrain ...[truncated 1211 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every direct dependency to an exact reviewed version. 2. Generate a lock file that includes all transitive dependencies. 3. Require package hashes, for example by using: ```bash pip install --require-hashes -r requirements.lock ``` 4. Add `requests` explicitly at a reviewed version because it is imported by runtime code. 5. Use a dedicated virtual environment instead of modifying the global Python environment. 6. Configure an approved package index explicitly and disable untrusted extra indexes. 7. Review binary wheels and platform-specific dependencies, particularly large OCR and machine-learning packages. 8. Use automated dependency scanning and controlled update pull requests. 9. Test dependency updates before modifying the lock file. 10. Document supported Python and operating-system versions to reduce resolver ambiguity. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
post_process.py:50
Finding
Predictable Shared Temporary Files Allow Symlink and File-Clobbering Attacks<![CDATA[ ## Vulnerability Details **File Location**: `post_process.py`, lines 50-66 **Vulnerability Type**: Unsafe predictable temporary files **Risk Level**: Medium ### Vulnerable Code ```python # Read file with open('/tmp/test_new_image.txt', 'r', encoding='utf-8') as f: lines = f.read().strip().split('\n') # Merge merged = merge_title_lines(lines) # Output result print("="*60) print("Optimized output:") print("="*60) for line in merged: print(line) # Save with open('/tmp/test_new_image_optimized.txt', 'w', encoding='utf-8') as f: f.write('\n'.join(merged)) print("\n✅ Saved to: /tmp/test_new_image_optimized.txt") ``` ### Technical Analysis The script uses fixed, globally predictable paths in `/tmp`. Shared temporary directories may be writable by other local users. The script does not verify file ownership, reject symbolic links, use exclusive creation, or perform an atomic replacement. Opening the output path with mode `w` truncates the resolved target before writing. If an attacker can pre-create the output as a symbolic link and the operating-system configuration permits following that link, the script can overwrite another file accessible to the victim. The fixed input path also permits data manipulation. Another user may replace the expected input before execution or between producer and consumer operations, causing the victim to process attacker-controlled content. Some systems enable protections such as `fs.protected_symlinks`, which may reduce exploitability in common `/tmp` configurations. The code should not rely on optional operating-system hardening, particularly if it may run in containers, unusual environments, or with elevated privileges. ### Attack Path A representative output-clobbering path is: 1. The attacker predicts that the victim will run `post_process.py`. 2. The attacker creates `/tmp/test_new_image_optimized.txt` as a symbolic link to a file writable by the victim. 3. The victim executes the script. 4. Pyt ...[truncated 1277 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace fixed `/tmp` names with files created through Python's `tempfile` module. 2. Use restrictive permissions and exclusive creation: ```python import tempfile with tempfile.NamedTemporaryFile( mode="w", encoding="utf-8", prefix="image_to_code_", suffix=".txt", delete=False ) as f: f.write("\n".join(merged)) ``` 3. Accept input and output paths as explicit command-line arguments rather than relying on shared global names. 4. Validate that an input is a regular file, is owned by the expected user, and is not a symbolic link. 5. For final outputs, write to a securely created temporary file in the destination directory and use `os.replace` for atomic publication. 6. Avoid running the script with elevated privileges. 7. If shared temporary storage is unavoidable, create a private directory with mode `0700`. 8. Add tests covering symbolic links, pre-existing files, concurrent execution, and permissions failures. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (55)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
声明描述的是一个完整的图片内容转换器:输入应为图片,输出应为特定代码格式,并能区分标题、正文、公式和图片。实际代码既不处理图片输入,也不进行 OCR、标题识别、正文转换或图片标记生成。它只定义了一个 optimize_formula(text) 函数,对已存在的公式文本做有限的格式替换,例如字母数字下标化、特定模式替换和括号转义,然后打印测试样例。因此其主要用途与声明明显不符,属于实质性能力缺失与目的不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
核心功能与描述大体一致:该脚本读取图片,执行 OCR,检测标题层级,区分正文/公式/图片,并生成类似 $word->titleN(...)、$word->body(...)、$word->formula(...) 和 ![image] 的输出。虽然描述中正文格式示例与代码实际输出字符串细节略有差异(描述写“正文=...=$F”样式,代码实际主要输出 $word->body("...");),这属于格式细节偏差,不是主要能力错配。真正的实质性不一致在于:声明未提及任何权限或外部资源访问,但代码默认优先初始化并调用百度 OCR,使用 requests 发起网络请求获取 access token 并上传图片进行识别。这意味着代码具备未声明的联网与数据外传能力,且还包含硬编码的 API 凭证,属于明显的未声明能力,因此应判定为不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
声明描述的是一个完整的图片内容解析与代码生成技能:应识别文字、公式、标题,并输出特定格式的代码。实际代码没有调用任何OCR、视觉模型或解析逻辑,也没有读取图片内容进行处理;它只是打印固定图片路径以及建议使用外部视觉AI服务的提示信息。因此,代码的主要行为与声明用途存在实质性不一致,应判定为不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
声明描述的是一个完整的图片转代码工具:输入应为图片,输出应为特定代码格式,并区分正文、公式、图片和不同级别标题。而实际代码只是一个本地测试脚本,包含正则规则 detect_title_level 和 extract_title_text,用于识别标题级别并去除编号前缀,然后打印测试用例结果。它没有任何图片输入处理、图像识别、文字提取、公式处理、图片标记输出,也没有生成诸如 $word->body(...)、$word->formula(...) 或 title1/title2/title3 的目标代码。因此其实际行为与声明的主要用途存在明显且实质性的差异。

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
声明描述的是一个完整的“图片转代码格式”技能,核心能力包括从图片中识别文字/公式/标题并输出特定格式代码。实际代码块只是一个独立的 Python 测试脚本:定义标题正则模式、提供 detect_title_level 函数、运行若干文本样例并打印测试结果。它确实涉及“自动识别标题级别”这一子能力,但缺少声明中的主要功能:没有任何图像处理、OCR、公式检测、正文/公式/图片的格式化输出。因此代码行为仅覆盖声明中的一小部分,且其主要用途更接近“标题识别逻辑测试”而非“图片内容转换器”,属于实质性不匹配。

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The code embeds Baidu OCR API credentials directly in source. Hardcoded secrets can be extracted by anyone with code access, enabling unauthorized API use, account abuse, billing impact, and making secret rotation difficult.

Missing User Warnings

High
Confidence
99% confidence
Finding
Using hardcoded OCR credentials without user warning combines secret exposure with undisclosed remote service dependency. Beyond account abuse risk, it prevents informed user consent about third-party processing and can hide operational/billing consequences.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The skill uploads image contents to Baidu OCR over the network, which can expose sensitive user data contained in documents, screenshots, formulas, or images. This is especially risky because the skill description suggests an image-to-code conversion utility and does not clearly disclose third-party transmission, so users may reasonably expect local-only processing.

Missing User Warnings

High
Confidence
98% confidence
Finding
The skill sends base64-encoded image data to a third-party OCR API without clear prior disclosure or consent. Users may process confidential documents, and silent transmission to an external provider materially increases privacy, compliance, and data-handling risk.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The file is entirely written in Chinese and its examples, OCR guidance, and output conventions assume Chinese usage by default. Because there is no user-facing note offering language choice or explaining that the skill is intentionally region/language-specific, this can violate a language/locale policy that requires opt-in rather than forcing a specific language.

Intent-Code Divergence

Medium
Confidence
88% confidence
Finding
Manifest 声称该技能会自动识别标题级别(title1/title2/title3),且前面多个示例也将章节标题转换为对应的 title 调用。但在该示例中,明显的章节标题“第三章 物理公式”“3.1 牛顿第二定律”“3.2 万有引力”却被输出为 body,和文档前述意图直接冲突,容易误导开发者对技能实际行为的理解。

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
This markdown report is written entirely in Chinese, including headings, labels, and explanatory text, with no indication that the skill is region-specific or that users may choose another language. Per the policy criteria, imposing a specific language without opt-in is a natural-language policy violation.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README instructs users to try a '视觉 AI 模式' and the '--vision-ai' parameter, but it does not disclose that image contents may be transmitted to an external API or service. Because this skill processes images that may contain sensitive text, formulas, or documents, the omission can lead users to unknowingly send confidential data off-host, creating privacy, compliance, and data-handling risks.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The README states that Baidu OCR is the default engine and that an API key is built in, which means user-supplied images may be transmitted to an external third-party service during ordinary use. For a skill presented simply as image-to-code conversion, this is dangerous because sensitive document images, formulas, or embedded text could be exfiltrated without clear user awareness or consent.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The README promotes Baidu OCR as the default path but does not clearly warn that images are uploaded to an external service for processing. This creates a meaningful privacy and data-governance risk, especially when users may process screenshots of internal documents, personal data, or proprietary technical materials under the assumption that conversion is local.

Lp3

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding
The skill documents and includes code paths that read local files, write output files, and optionally send image content to third-party vision/OCR services, but it does not declare any tool scope or permissions. In an agent setting, missing scope declarations can cause users or orchestrators to underestimate what the skill may access or exfiltrate, especially when screenshots may contain sensitive document data.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
The embedded code initializes OCR with `ocr_lang='ch'`, and the configuration example also sets `ocr_lang` to `ch`, which imposes a specific language/locale default. The document does not present this as an explicit user choice or justify it as a region-specific skill, so it conflicts with the language/locale policy criterion.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The skill description says formulas are recognized and converted to $word->formula("...") output, but formula_to_latex is only a stub with pass. Because formula conversion is a central advertised feature and the implementation is absent, the skill's described behavior materially exceeds the actual code.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The manifest and surrounding documentation claim the skill automatically recognizes title levels and emits $word->title1/title2/title3 output, but the actual conversion logic only handles 'text', 'formula', and 'image'. There is no title classification or title-specific output path in the provided implementation, so the documented core behavior does not match what the code actually does.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill promotes optional use of external vision-AI providers for processing images without an explicit privacy warning about sending potentially sensitive screenshots to third parties. In this skill’s context, inputs are document images that may contain confidential text, formulas, or business data, so omission of a disclosure increases data-exposure risk.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The report recommends Baidu/Tencent OCR APIs and vision models as improved solutions but does not warn that image content may be transmitted to external providers. Because this skill processes images that may contain sensitive text, formulas, or document content, users could unknowingly send confidential data off-device, creating privacy, compliance, and data-handling risks.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The markdown describes Baidu OCR API usage without warning that uploaded images and extracted text may be sent to a third-party cloud provider. Because the skill processes technical documents that may contain proprietary or sensitive information, this omission can lead to inadvertent confidentiality breaches and regulatory/privacy issues.

Static analysis

No suspicious patterns detected.