Back to skill

Security audit

Venice.Ai Router Openclaw

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real Venice.ai router, but its privacy and budget controls are over-promised and can fail in ways that expose sensitive prompts or create unexpected costs.

Review this before installing if you handle confidential data. Do not rely on --private-only or VENICE_PRIVATE_ONLY as a hard guarantee in this version, avoid premium or explicit model overrides for sensitive prompts, and treat web search, conversation files, and tool definitions as data that may leave your machine. Also treat budget settings as soft routing guidance rather than a strict spending limit.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/venice-router.py:344
Finding

Private-Only Mode Can Silently Route Sensitive Data to Non-Private Models

Content
View full analysis

Vulnerability Details

File Location: scripts/venice-router.py:344-348
Related bypass: scripts/venice-router.py:1071-1074
Vulnerability Type: Fail-open privacy enforcement
Risk Level: High

Vulnerable Code

python
# Apply private_only filter
if private_only:
    candidates = [m for m in models if m.get("private", False)]
    if not candidates:
        # Fall back to all models if no private ones in this tier
        candidates = models
else:
    candidates = models

The direct model-selection path also bypasses the private-model constraint:

python
if args.model:
    model_id = args.model
    model_name = args.model
    tier_name = "custom"

Technical Analysis

The --private-only option is documented as restricting inference to private models with zero data retention and no external-provider proxying. The implementation does not enforce this as a security invariant.

When the selected tier has no private candidates, select_model() silently restores the complete model list. The premium tier consists entirely of models marked private: False; therefore, selecting that tier while private-only mode is enabled can still select an anonymized model that Venice may proxy to an external provider.

The direct --model path also accepts an arbitrary model identifier without checking whether it is private. This permits a caller to combine private-only mode with a known non-private model while the status output still includes the private-only flag.

Before transmission, the program constructs messages from the system prompt, full conversation history, and current user prompt. It then serializes that content into the API request. Consequently, this flaw affects all sensitive content submitted under the purported privacy guarantee, not merely routing metadata.

Attack Path

  1. A user enables --private-only or sets VENICE_PRIVATE_ONLY=true because the prompt or conversation contains confidential information.
  2. On ...[truncated 1355 chars]
Remediation
View remediation

Remediation Suggestions

  1. Fail closed when no private model is available

    Replace the fallback with an explicit error:

    python
    if private_only:
        candidates = [m for m in models if m.get("private", False)]
        if not candidates:
            raise ValueError(
                f"No private model is available in tier {tier!r}; "
                "refusing to relax private-only mode."
            )
    else:
        candidates = models
    
  2. Validate explicit model overrides

    Resolve --model against authoritative model metadata. When private-only mode is active, reject unknown models and any model whose private property is not explicitly True.

  3. Enforce the invariant immediately before transmission

    Add a final check before calling venice_chat():

    python
    if private_only:
        if not model_info or model_info.get("private") is not True:
            print(
                "Private-only mode requires a verified private model.",
                file=sys.stderr,
            )
            sys.exit(1)
    

    This defense-in-depth check prevents future routing branches from accidentally bypassing privacy enforcement.

  4. Do not label a request private-only unless enforcement succeeded

    Only display the private-only status after the final selected model has been verified as private.

  5. Add regression tests

    Cover at least:

    • Private-only mode with the premium tier
    • Private-only mode with an explicit non-private model
    • Private-only mode with an unknown custom model
    • Automatic premium classification under private-only mode
    • Interactions with tier caps, uncensored mode, thinking mode, and budget downgrades
    • Verification that no network request occurs after privacy validation fails
  6. Clarify trust boundaries

    Documentation should accurately explain that prompts are transmitted to Venice and that privacy properties depend on the selected model and Venice's service guarantees. Av ...[truncated 101 chars]

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (19)

Natural-Language Policy Violations

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README markets the platform as 'uncensored' with 'no content filters, no refusals,' which explicitly frames the skill as a way to bypass safety controls. In an agent skill context, that positioning increases the likelihood of harmful, abusive, or policy-violating use and encourages operators to adopt the tool for risky workflows without guardrails.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The CLI docs directly advertise an 'Uncensored Mode' as having 'no content filters, no refusals,' making harmful-output enablement an explicit feature rather than an implementation detail. Because this is operational guidance, it lowers friction for misuse and normalizes using the router to evade provider safety restrictions.

Content

No source excerpt is available for this finding.

External Model or Provider Selection

High
Category
Excessive Agency
Confidence
90% confidence
Finding

Skill selects an external model or provider that may use a different account or billing plan than the operator expects. Undisclosed model switches can cause unexpected cost or quota consumption.

Content

Scanner excerpt · scripts/venice-router.py (reported line 903)May include surrounding context.

python
%(prog)s --budget-status
  %(prog)s --classify "Design a microservices architecture"
  %(prog)s --list-models
  %(prog)s --model deepseek-v3.2 --prompt "Hello"
        """,
    )

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 100)May include surrounding context.

Copy the files to your OpenClaw skills directory:

bash
mkdir -p ~/.openclaw/workspace/skills/venice-router
cp -r SKILL.md scripts/ references/ ~/.openclaw/workspace/skills/venice-router/

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The web-search feature is documented as a simple capability enhancement without a clear warning that user queries will be sent to external search infrastructure and may expose sensitive or regulated information. Users may assume all processing remains within Venice or private models, especially given the strong privacy marketing elsewhere in the README.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README states that the router prefers private models over anonymized ones, and that anonymized mode proxies requests to external providers, but it does not prominently warn that prompts, conversation history, tools, or sensitive inputs may leave Venice infrastructure depending on model choice. In a routing skill explicitly marketed for privacy, this omission can mislead users into disclosing confidential data under incorrect assumptions.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises executable capabilities including environment access, file read/write, network access, and shell execution, but does not declare any explicit tool scope or permissions boundary. This increases the chance that a user or host system invokes the skill with broader authority than expected, making unintended data access, exfiltration, or command execution harder to audit and constrain.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The invocation text is very broad and can cause the skill to be selected for generic chat, coding, privacy, or model-selection requests that users may not realize will be routed to a third-party service. Overbroad matching increases the likelihood of accidental activation, which can result in unintentional transmission of sensitive prompts, conversation history, or tool-related data outside the local environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill emphasizes privacy benefits, but it does not clearly warn that prompts, conversation history, tool definitions, and optional web-search-related content may be sent to Venice.ai and potentially onward to external search or tool endpoints. That omission can mislead users into sharing confidential information under an incomplete understanding of where their data is transmitted, especially given the strong privacy-focused marketing language.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.sh (reported line 22)May include surrounding context.

sh
echo "🦞 Installing venice-router skill..."
echo "   Target: $TARGET"

mkdir -p "$TARGET/scripts" "$TARGET/references"

cp "$SCRIPT_DIR/SKILL.md" "$TARGET/SKILL.md"
cp "$SCRIPT_DIR/scripts/venice-router.py" "$TARGET/scripts/venice-router.py"

Ssd 1

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill description advertises support for 'uncensored' routing and 'no content filters, no refusals,' which semantically encourages bypass of provider safety controls. In an agent skill, that increases the likelihood of facilitating harmful or policy-evading outputs, especially when exposed as a convenience feature.

Content

No source excerpt is available for this finding.

Ssd 1

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The CLI examples explicitly promote --uncensored usage as a feature, normalizing model selection intended to avoid filtered/refusal behavior. That makes misuse easier by giving users a documented path to seek less restricted generations.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/models.md (reported line 89)May include surrounding context.

md
# ── Venice.ai API ────────────────────────────────────────────────────────────

VENICE_API_BASE = "https://api.venice.ai/api/v1"

# ── Model Tiers (sorted cheapest → most expensive) ──────────────────────────
# Prices per 1M tokens [input_usd, output_usd]

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/venice-router.py (reported line 40)May include surrounding context.

python
# ── Venice.ai API ────────────────────────────────────────────────────────────

VENICE_API_BASE = "https://api.venice.ai/api/v1"

# ── Model Tiers (sorted cheapest → most expensive) ──────────────────────────
# Prices per 1M tokens [input_usd, output_usd]

Ssd 1

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The selection logic actively prioritizes models flagged uncensored when prefer_uncensored=True, operationalizing safety-bypass intent in code rather than merely documenting it. This turns potentially harmful routing into a built-in mechanism that can systematically steer requests to less restricted providers.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The --private-only option is documented and presented as enforcing use of private/zero-retention models, but select_model() explicitly falls back to all models in the tier when no private candidates exist. That creates a confidentiality breach risk because users may send sensitive prompts believing external/non-private providers are excluded when they are not.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Enabling web_search adds provider-specific search behavior that can cause user prompt content to be forwarded beyond the core model path, yet the code does not require explicit acknowledgement of the added privacy exposure. This is particularly sensitive because users may assume the 'privacy-first' positioning applies equally to search augmentation.

Content

No source excerpt is available for this finding.

Ssd 1

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The argument help text describes uncensored models as having 'no content filters, no refusals,' which directly frames the option as a safety-bypass capability. In combination with the router's automation features, this increases abuse potential and user intent to evade safeguards.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script appends conversation history and the current prompt into messages and sends them to the Venice API, but the UX does not provide a clear disclosure or confirmation that this content leaves the local environment. In a privacy-focused router, that can mislead users into transmitting sensitive history to an external service without informed consent.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.