Back to skill

Security audit

Pattern

Security checks for vulnerabilities and agentic risk

Overview

The skill’s marketing workflow is plausible, but its bundled worker exposes cloud-backed processing too broadly and under-discloses important data flows.

Install or run this only in a controlled environment after adding authentication, rate limits, URL allowlisting or direct uploads, download size/time limits, strict metadata schemas, Drive destination controls, and clear disclosure that Anthropic, Google Vertex AI, Redis, and Google Drive may receive or store product data.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
jewellery_openclaw_skill.py:190
Finding

Unauthenticated Endpoint Permits Abuse of Privileged Cloud Services

Content
View full analysis

Vulnerability Details

File Location: jewellery_openclaw_skill.py, lines 190-205
Vulnerability Type: Missing authentication, authorization, and abuse controls
Risk Level: High

Vulnerable Code

python
@app.post("/api/v1/jewellery/process")
async def process_jewellery_content(payload: WebhookPayload):
    # This acts as the synchronous webhook return, processing in background if needed
    # Wait for completion to return real results for integration ease.
    import os
    parent_folder = os.getenv("DRIVE_FOLDER_ID", "root") 
    result = await run_pipeline(payload, parent_folder)
    
    if result["status"] == "error":
        raise HTTPException(status_code=500, detail=result["message"])
        
    return result

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

Technical Analysis

The processing endpoint is exposed on all network interfaces and does not require an API key, authenticated service identity, signed webhook, or user session. It also lacks authorization checks, request quotas, and rate limiting.

Every accepted request can invoke operations using the application's configured Anthropic, Vertex AI, Redis, and Google Drive credentials. The endpoint therefore allows an unauthenticated caller to indirectly exercise the application's cloud privileges, even though the caller does not possess the underlying credentials.

A cache hit only occurs for an identical downloaded image hash. An attacker can bypass caching by supplying unique image resources or changing the image bytes for every request.

Attack Path

  1. An attacker discovers or reaches TCP port 8000 on the host.
  2. The attacker sends a POST request to /api/v1/jewellery/process with an arbitrary image_url, product_name, and metadata.
  3. The application downloads the image and invokes Anthropic prompt generation.
  4. It starts two billable Vertex Imagen ...[truncated 915 chars]
Remediation
View remediation

Remediation Suggestions

  • Require authentication using a service-to-service identity mechanism, OAuth access token, or high-entropy API key.
  • For webhooks, require an HMAC signature that covers the timestamp and raw request body. Reject expired timestamps and replayed request identifiers.
  • Authorize each authenticated principal for the requested operation and configured Drive destination.
  • Place the service behind an authenticated API gateway or private network rather than exposing Uvicorn directly.
  • Add per-principal and global rate limits, concurrency limits, daily generation quotas, and billing alerts.
  • Enforce request deduplication and reject excessive queued work.
  • Use a dedicated Google service account with access only to the intended Drive folder.
  • Return generic client-facing errors and record detailed provider errors only in access-controlled logs.

T09 · Insecure Skill Coding Practices

Error
Location
jewellery_openclaw_skill.py:57
Finding

Server-Side Request Forgery Through User-Controlled Image URL

Content
View full analysis

Vulnerability Details

File Location: jewellery_openclaw_skill.py, lines 57-61 and line 143
Vulnerability Type: Server-Side Request Forgery
Risk Level: High

Vulnerable Code

python
async def download_image(url: str) -> bytes:
    async with httpx.AsyncClient() as client:
        response = await client.get(url)
        response.raise_for_status()
        return response.content

The function is invoked with a directly user-controlled value:

python
async def run_pipeline(payload: WebhookPayload, folder_id_root: str):
    try:
        # Step 1: Input & Hash Check
        image_bytes = await download_image(payload.image_url)
        img_hash = get_image_hash(image_bytes)

Technical Analysis

payload.image_url is fetched by the server without validating its scheme, hostname, port, or resolved IP address. There is no allowlist and no rejection of loopback, private, link-local, multicast, or otherwise reserved network ranges.

The code also does not verify that the response is an actual image before reading it. Consequently, an attacker can instruct the server to send requests to resources reachable from the worker's network context, including internal HTTP services and cloud instance metadata endpoints.

Redirect behavior must also be controlled as part of remediation. Even if initial hostname validation were added, an attacker-controlled endpoint could potentially redirect the request to a prohibited destination if each redirect target and resolved address were not independently checked.

Attack Path

  1. An attacker submits a request to /api/v1/jewellery/process.
  2. The image_url field is set to an internal destination, such as a loopback service, private-network host, or cloud metadata address.
  3. download_image performs the request from the application server's network position.
  4. The internal response is fully read into memory and hashed.
  5. Dependin ...[truncated 923 chars]
Remediation
View remediation

Remediation Suggestions

  • Prefer authenticated direct file uploads instead of server-side retrieval from arbitrary URLs.
  • If URL retrieval is necessary, allowlist trusted HTTPS origins and reject all other schemes and destinations.
  • Resolve the hostname before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges.
  • Prevent DNS rebinding by ensuring the validated address is the address used for the connection.
  • Disable redirects or validate every redirect target using the same scheme, host, port, and IP checks.
  • Restrict destination ports to the ports genuinely required, normally TCP 443.
  • Apply egress firewall rules that prevent the worker from connecting to metadata services and sensitive internal networks.
  • Verify the response MIME type and decode it with a trusted image library before further processing.
  • Do not rely only on hostname string comparisons, because alternate IP encodings, IPv6, redirects, and DNS changes can bypass simplistic filters.

T09 · Insecure Skill Coding Practices

Error
Location
jewellery_openclaw_skill.py:57
Finding

Unbounded Remote Download Enables Resource-Exhaustion Attacks

Content
View full analysis

Vulnerability Details

File Location: jewellery_openclaw_skill.py, lines 57-61
Vulnerability Type: Unrestricted resource consumption
Risk Level: High

Vulnerable Code

python
async def download_image(url: str) -> bytes:
    async with httpx.AsyncClient() as client:
        response = await client.get(url)
        response.raise_for_status()
        return response.content

Technical Analysis

The implementation buffers the complete remote response through response.content. It does not enforce an application-level maximum response size, inspect Content-Length, stream data with a hard byte cap, or validate decoded image dimensions.

The client is also instantiated for every request without an explicit project-specific timeout policy or shared connection limits. An attacker-controlled server can return oversized content or transmit data slowly. Concurrent malicious requests can retain sockets, tasks, and memory for prolonged periods.

MIME type alone is insufficient as a defense because it can be forged. Image decoding must also enforce a maximum pixel count to prevent compressed image bombs whose network size is small but decoded memory use is very large.

Attack Path

  1. An attacker hosts a URL that returns a very large body, an endless stream, or data transmitted at a deliberately slow rate.
  2. The attacker submits that URL as image_url.
  3. The worker opens a connection and attempts to buffer the complete response.
  4. The attacker sends multiple concurrent API requests.
  5. Worker memory, sockets, asynchronous tasks, and execution capacity are progressively exhausted.
  6. Legitimate requests become slow or fail, and the process may be terminated due to out-of-memory conditions.

Impact Assessment

A remote attacker who can reach the processing endpoint can degrade or terminate the service without cloud credentials. Depending on deployment limits and concurrency, the attack ...[truncated 296 chars]

Remediation
View remediation

Remediation Suggestions

  • Stream the response rather than accessing response.content.
  • Set strict connect, read, write, pool, and total operation timeouts.
  • Reject responses whose declared Content-Length exceeds a small, documented image limit.
  • Terminate streaming as soon as the actual downloaded byte count exceeds that limit, regardless of the declared length.
  • Validate file signatures and safely decode the image after downloading.
  • Enforce maximum width, height, frame count, and total decoded pixel count.
  • Reject animated or multi-frame image formats unless they are explicitly required.
  • Reuse a configured HTTP client with bounded connection pools.
  • Add endpoint-level request size, concurrency, and rate limits.
  • Run image parsing in a resource-constrained process where practical.
  • Cancel downstream tasks immediately when input validation or download processing fails.

T09 · Insecure Skill Coding Practices

Warning
Location
jewellery_openclaw_skill.py:67
Finding

Prompt Injection Through Arbitrary Product Metadata

Content
View full analysis

Vulnerability Details

File Location: jewellery_openclaw_skill.py, lines 67-96 and lines 153-156
Vulnerability Type: Untrusted data embedded directly into model instructions
Risk Level: Medium

Vulnerable Code

python
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
async def generate_prompts(image_url: str, metadata: dict) -> dict:
    prompt = f"Analyze this jewellery piece context: {metadata}. Provide ONLY a JSON with two keys: 'model_prompt' (describing an AI model wearing it naturally) and 'product_prompt' (studio lighting for the product alone)."
    
    response = await aclient.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=500,
        system="You are an expert jewellery art director.",
        messages=[{
            "role": "user",
            "content": [
                {"type": "image", "source": {"type": "url", "url": image_url}},
                {"type": "text", "text": prompt}
            ]
        }]
    )
    # Simplified JSON extraction
    import json
    return json.loads(response.content[0].text)

@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
async def generate_content(product_name: str, metadata: dict) -> str:
    prompt = f"Write a catchy Instagram caption and a short SEO product description for {product_name}. Details: {metadata}"
    response = await aclient.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=600,
        system="You are a luxury jewellery copywriter.",
        messages=[{"role": "user", "content": prompt}]
    )
    return response.content[0].text

Model-generated prompt fields are then trusted as Imagen input:

python
model_img_task = asyncio.create_task(generate_imagen_asset(prompts['model_prompt']))
prod_img_task = asyncio.create_task(generate_imagen_asset(prompts['produc
...[truncated 2521 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace Dict[str, Any] with a strict Pydantic model containing only required product fields.
  • Forbid unknown fields and nested arbitrary objects.
  • Enforce conservative length, type, numeric range, and character restrictions on every field.
  • Serialize product data in a clearly delimited structured block and explicitly identify it as untrusted data, not instructions.
  • Use provider-supported structured output or tool schemas rather than relying on a request for JSON in natural language.
  • Validate the response against a strict schema requiring exactly model_prompt and product_prompt as bounded strings.
  • Reject unexpected fields, excessive lengths, control characters, URLs, or instructions unrelated to jewellery generation.
  • Apply an independent content-policy check before sending generated prompts to Imagen.
  • Treat model output as untrusted throughout the pipeline.
  • Limit retries to transient provider and transport failures; do not automatically retry deterministic JSON-schema or policy-validation failures.
  • Add tests using common prompt-injection patterns and verify that they cannot alter the output schema or downstream task.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

This is a significant description-behavior mismatch: the skill claims a Vertex AI/Google Drive workflow but reportedly also uses Anthropic Claude, exposes an HTTP webhook, uses Redis, and downloads arbitrary external image URLs. Undeclared external services and ingress points materially expand the attack surface, create privacy/compliance risk, and can allow SSRF-style retrieval or unauthorized triggering of processing.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill metadata says it uses Google Vertex AI and Google Drive, but the code also initializes and sends image URLs, product names, and metadata to Anthropic Claude. This is a meaningful security and privacy transparency issue because users and reviewers may approve the skill under a different data-sharing assumption than what the code actually does.

Content

No source excerpt is available for this finding.

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · pattern_jewellery_openclaw_system.html (reported line 335)May include surrounding context.

html
<main>

<!-- ═══════════════════════════════════════════════════
     COMPONENT 1: SKILL SCHEMA
═══════════════════════════════════════════════════ -->
<section class="component">

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · pattern_jewellery_openclaw_system.html (reported line 551)May include surrounding context.

html
]</pre></div>
</section>

<!-- ═══════════════════════════════════════════════════
     COMPONENT 3: PROMPT TEMPLATES
═══════════════════════════════════════════════════ -->
<section class="component">

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises no explicit tool scope while its bundled components reportedly use environment access and network operations. That creates a trust and review gap: consumers cannot accurately assess what the skill may access or invoke, and hidden capability can enable unexpected data exfiltration or external communications.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill outputs a Drive link and states assets are uploaded to Google Drive, potentially as public or internal links, but does not clearly warn users before upload/exposure. That can lead to accidental disclosure of product images, generated marketing materials, or embedded metadata to unintended audiences.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill declares persistent memory fields and a 30-day cache keyed on user content and metadata, but does not provide a clear privacy notice or retention consent. Persistent storage of prompts, images, captions, and metadata increases the risk of unintended reuse, data leakage, and noncompliance with retention or deletion expectations.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest describes broad automation behavior but does not define when the skill may be invoked, by whom, or under what approved inputs and contexts. In a workflow that can generate media and upload assets to Google Drive, missing trigger and scope boundaries increases the chance of unintended execution, misuse on unauthorized content, or silent processing of sensitive product data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill hard-codes a target market as 'Gulf luxury' without any user opt-in or runtime parameterization. While not directly a code execution issue, this can cause unauthorized profiling or region-specific content generation that may be inappropriate, noncompliant, or misaligned with user intent, especially in automated marketing workflows.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The implementation routes text-generation tasks to Claude instead of the declared Gemini-based provider, creating a mismatch between stated and actual data flows. While not code-execution dangerous by itself, it weakens informed consent, compliance review, and vendor risk controls because sensitive business content may be processed by an undeclared third party.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code forwards an external image URL and metadata to Anthropic for prompt generation without any visible consent, warning, or policy enforcement in the skill. Because jewellery product images and metadata may contain proprietary catalog information or customer-linked data, undisclosed transfer to a third-party AI service creates privacy, confidentiality, and compliance risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Product name and metadata are sent to an external LLM without clear disclosure or approval controls. In a marketing automation context, this can leak embargoed product details, internal naming, or commercially sensitive attributes to an outside provider, especially where manifests suggest a different provider stack.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill uploads generated images and text to Google Drive using service-account credentials without any visible user-facing notice or access-scope safeguards in this file beyond drive.file. This can unintentionally persist potentially sensitive generated content in cloud storage and share links, creating retention and access-control risk if operators do not realize data is being stored externally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill automatically uploads generated assets and metadata to Google Drive but does not clearly warn the user that outputs will be stored externally or may become shareable. This creates a privacy and data-governance risk because users may provide product images and commercial details without informed consent about storage location and sharing implications.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documented skill metadata says the system uses Google Vertex AI (Gemini and Imagen), but the implementation also sends text-generation workloads to Anthropic Claude. This is a real security and governance issue because operators and users may make data-handling decisions based on incomplete vendor disclosure, causing undisclosed third-party transmission of product data and prompts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The workflow transmits product images, prompts, and product details to multiple third-party services—Anthropic, Google Vertex/Imagen, and Google Drive—without explicit disclosure in the skill flow. This is dangerous because it undermines informed consent, vendor-risk review, and data-classification controls for potentially sensitive business assets.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

The file explicitly defines an external API endpoint for Anthropic, confirming outbound transmission to a third-party service. External transmission is not inherently malicious, but in this context it matters because the vendor is not fully aligned with the declared stack and there is no explicit disclosure of what data leaves the environment.

Content

Scanner excerpt · pattern_jewellery_openclaw_system.html (reported line 436)May include surrounding context.

html
{
    <span class="tok-key">"tool_name"</span>: <span class="tok-str">"claude_llm"</span>,
    <span class="tok-key">"description"</span>: <span class="tok-str">"Anthropic Claude for prompt generation and social content creation"</span>,
    <span class="tok-key">"api_endpoint"</span>: <span class="tok-str">"https://api.anthropic.com/v1/messages"</span>,
    <span class="tok-key">"auth_method"</span>: <span class="tok-str">"bearer_token"</span>,
    <span class="tok-key">"auth_header"</span>: <span class="tok-str">"x-api-key"</span>,
    <span class="tok-key">"model"</span>: <span class="tok-str">"claude-3-5-haiku-20241022"</span>,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

SQP-3 applies to all file types and covers language or locale policy violations in natural-language instructions. This template hard-codes a specific regional identity and market orientation for generated content, rather than making it configurable or clearly justified as a region-specific compliance requirement.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The model prompt is defined as targeting the Gulf luxury market, which imposes a locale/market orientation in the natural-language instructions. The file does not indicate that users can choose a different locale or that this regional constraint is optional or justified as a region-specific skill.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The stated purpose is jewellery product marketing automation using Vertex AI and Google Drive. Adding Redis for persistent caching is an extra infrastructure capability not mentioned in the manifest and not obviously part of the declared toolset, even though it supports efficiency rather than core business logic.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

This code loads Google service-account credentials from a path provided by an environment variable, which is access to sensitive credentials material. The file includes configuration comments, but no explicit user-facing disclosure that credentialed cloud access is required and used.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The inline comment says the endpoint processes in background if needed, suggesting asynchronous fire-and-forget behavior. The code immediately awaits run_pipeline and does not use BackgroundTasks, so the implemented behavior is synchronous request processing until completion.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The memory section states that after updating background_preference, the Creative Agent will inject it into Template 2 at {background_preference}. But Template 2 hardcodes 'white Carrara marble with deep navy velvet accent' and includes no {background_preference} variable, so the comment actively misdescribes how the prompt works.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.