T09 · Insecure Skill Coding Practices
- Location
dist/lib/api-client.js:68- Finding
Arbitrary Local File Read and Exfiltration Through the Image Upload Tool
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill appears to perform ecommerce asset generation, but it asks for broad account access and handles local files and URLs with too little restriction.
Review before installing. Use it only with a trusted AI Product Space instance, verify the OAuth grant is acceptable, and avoid giving it paths or URLs unless you are sure the content is safe to upload. A safer version should use narrow OAuth scopes, validate API origins, restrict file uploads to confirmed image files, and block private or oversized URL fetches.
dist/lib/api-client.js:68Arbitrary Local File Read and Exfiltration Through the Image Upload Tool
dist/lib/api-client.js:82Server-Side Request Forgery and Unbounded Response Buffering in URL-Based Image Upload
dist/index.js:71OAuth Access Token or API Key Can Be Forwarded to an Arbitrary Configured Endpoint
claw.json:19OAuth Configuration Requests Unrestricted Wildcard Scope
There is a clear description-behavior mismatch. The declared purpose promises an end-to-end ecommerce asset generator from one uploaded white-background product image, covering multiple output modalities and asset types. The actual code chunk only exposes a tool named 'generate_single_image' that calls client.generateImage(space_id, prompt, { n: count }) to create up to a few images from a custom prompt. Its primary purpose is much narrower: single/multiple image generation via text prompt. The code neither ingests a source product photo nor produces marketing text or video, so the declared description materially overstates the implemented functionality.
There is a material description-to-behavior mismatch. The declared purpose promises an end-to-end ecommerce asset suite from a single product image, covering multiple asset types beyond video. However, the provided code chunk implements only one narrow function: generating an 8-second product showcase video from 1–2 image URLs, with optional waiting for completion. No logic exists here for producing product main images, scene images, posters, or marketing copy. This is not just an implementation detail; it changes the primary capability represented by the description. The code’s own manifest description is narrower and consistent with video-only behavior, which further supports that the top-level declared description overstates what this chunk actually does.
The declared description promises asset generation from a product photo, including images, posters, copy, and video. However, this code chunk does not generate any ecommerce assets or process an uploaded image. Its primary function is to inspect an existing workspace and report status/progress, optionally formatting already-produced pipeline outputs when available. That is a materially different purpose from the declared end-user functionality. While status checking could be a supporting tool inside a larger asset-generation system, this specific code chunk itself is not accurately represented by the declared description.
The declared description emphasizes asset generation from an uploaded product image as the skill's main purpose. However, the actual code only implements a browsing/listing function (list_assets) for previously generated assets via client.listAssets. This is a materially different primary purpose: retrieval and summarization of existing resources rather than generation of new content. While listing assets could be a supporting tool within a broader ecommerce-asset workflow, this specific code chunk does not perform the declared core capability, so the description does not accurately represent the supplied code.
The declared description promises an end-user outcome: automatic generation of complete ecommerce creative assets from one product image. However, the actual code chunk implements only a single helper tool named 'upload_product_image' that uploads an image into a workspace. It neither invokes a generation pipeline nor produces any of the advertised outputs such as product main images, scene images, selling-point posters, copy, or video. The returned message explicitly indicates that generation is a separate next step ('run_ecommerce_pipeline'), confirming that this code is only an input-preparation step. Therefore the description materially overstates the code's actual behavior and primary purpose.
The trigger "generate product" is ambiguous and incomplete, making unintended activation particularly likely. Because the skill can initiate authenticated workflows and upload user-provided images or URLs to a remote service, misrouting requests could expose sensitive business assets or prompt unauthorized external processing.
The skill declares OAuth auth and multiple network-capable tools, but it does not define an explicit permission or allowed-tools scope. In practice, this weakens least-privilege guarantees and can let the runtime expose broader environment or network capabilities than users or reviewers can easily verify from the manifest.
The trigger phrase "商品图" is broad enough to match many ordinary product-image requests, which can cause unintended skill activation. Over-broad activation is dangerous because it may route user content, images, or auth flows to this third-party service when the user intended a more generic task.
The trigger phrase "product images" is extremely generic and may fire on unrelated image-editing or catalog requests. In a skill that can invoke OAuth and send user assets to an external service, accidental activation increases privacy and consent risk.
The skill requests OAuth scope "*", which grants unrestricted access despite the skill only needing functionality related to ecommerce asset generation. This violates least-privilege principles and means that if the skill, backend, or issued token is abused, an attacker could gain broad access to unrelated user data or account capabilities exposed by the AI Product Space service.
This code returns error and status messages only in Chinese, including authorization, configuration, unknown-tool, and execution-failure responses. Because the file provides no user language selection or documented locale constraint, it violates the language/locale policy criterion.
This method reads a local file from disk and transmits its contents to a remote API endpoint. Although uploading appears related to the client purpose, the code provides no user-facing notice, confirmation, or inline documentation warning that local file data will be sent externally.
The code fetches data from a user-supplied URL and then uploads the retrieved content to the API, which can transmit user-provided or system-accessed data over the network. There is no confirmation prompt, visible logging, or explanatory comment/docstring warning that external URLs will be contacted and their contents forwarded.
The pipeline request defaults the language parameter to 'zh' when no language is provided, which imposes a specific locale automatically. This is a natural-language policy concern because the code does not offer explicit user choice or document a justified region-specific constraint.
The handler returns user-facing strings such as '部分完成', '已完成', '工作空间', and '流水线状态' directly in Chinese. This imposes a specific language on all users without any visible locale selection or opt-in, which matches the policy category for language or locale constraints.
The formatter hard-codes Chinese user-facing strings in the completion header and footer. This creates a locale policy concern because the skill presents output in a specific language without any visible user choice, opt-in, or documented region-specific justification in this file.
The manifest description is primarily in Chinese and several user-facing return strings are only in Chinese, while the skill exposes a multilingual language parameter for output. This creates a language policy issue because the skill communicates in a fixed language by default rather than clearly offering or honoring user-facing language choice for all responses.
The tagline and description force a specific language for the skill's natural-language presentation, and the file does not indicate that users can opt into another interface language. Under the policy, locale or language constraints should either offer user choice or be clearly documented and justified.
The handler returns a fixed Chinese-language success message and next-step instruction, with only a tool name in English. This imposes a specific language on users without offering a choice or documenting a justified locale constraint, which matches the language-policy violation criteria.
The returned user-facing strings are written in Chinese, including status and asset summary messages, with no indication that the user can choose a language or locale. This may violate a language/locale policy when users are not explicitly opted into Chinese output.
All user-facing content in the example is presented only in Chinese, and there is no indication that the language is user-selected or that the skill is intentionally restricted to a Chinese-language locale. This can violate language/locale policy when a skill forces a specific language without opt-in.
The example instructs the assistant to use a previously established workspace ('你之前的工作空间') without telling the user that prior workspace state or stored assets may be reused. In a skill that generates ecommerce media, hidden reuse of workspace context can unintentionally expose prior customer/product data, apply stale settings, or produce outputs influenced by earlier sensitive content.
This manifest includes multilingual keywords, including Chinese terms, but provides no natural-language indication of how the skill handles language or whether output language follows user preference. Because language/locale policy findings apply to all file types, this can be flagged as an undocumented locale behavior risk in user-facing metadata.
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
],
"license": "MIT",
"devDependencies": {
"typescript": "^5.0.0"
},
"engines": {
"node": ">=18.0.0"
No suspicious patterns detected.