Back to skill

Security audit

free-tier-ai-router

Security checks across malware telemetry and agentic risk

Overview

The skill is a coherent AI API router, but it handles API keys, sends prompts to multiple outside providers, writes persistent local cache/state, and uses broad install/setup behavior that users should review first.

Install only if you are comfortable with this skill using your AI provider API keys, sending prompts/system text to selected third-party providers, and storing response cache/state under your home directory. Avoid passing API keys on the command line on shared systems; use non-sensitive prompts for probes; run with --no-cache for sensitive work; and review get-ai-router.sh before using the one-file bootstrap.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (33)

Tainted flow: 'prompt' from sys.stdin.read (line 567, user input) → open (file write)

Medium
Category
Data Flow
Content
if use_cache:
                try:
                    json.dump({'text': text, 'provider': prov, 'model': model},
                              open(cache_path(prompt, system, task,
                                              max_tokens, quality), 'w'))
                except Exception: pass
            return text, prov, model, False
Confidence
81% confidence
Finding
open(cache_path(prompt, system, task, max_tokens, quality), 'w'))

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill declares substantial capabilities in metadata and documentation: outbound network access, reading provider credential files, shelling out to curl/python3, and persisting state to disk. The finding text says 'no declared permissions,' but the actual content shows these capabilities are present and operational, which means the skill can exfiltrate prompts and use sensitive API keys if installed without a stronger permission model. In context this is expected functionality for an API router, but it is still a real risk surface rather than a harmless false alarm.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The bootstrap script performs more than a simple install: it runs `npx` to fetch and execute a remote package (`clawhub@latest`), writes files under `~/.ai-router`, and drops a new executable wrapper at `~/ai`. This expands the trust boundary significantly because installation executes network-sourced code and modifies the user's home environment, which can be abused if the upstream package or transport is compromised.

Description-Behavior Mismatch

Medium
Confidence
74% confidence
Finding
The skill advertises routing across Cerebras free-tier keys, but no Cerebras routes exist in ROUTES, so configured Cerebras credentials will never be selected. This is primarily an integrity and reliability issue that can mislead operators into believing a provider is available for failover when it is not.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The embedded router includes `--setup` logic that accepts an API key, auto-detects a provider, writes credentials to `~/.config/<provider>/credentials.json`, and persists state/cache files under the user's home directory. That exceeds a pure routing role and materially increases the skill's privilege and secret-handling scope, creating risk if the skill is invoked in unattended contexts or reviewed only as a router.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The file explicitly states that probes were run against live APIs with real completions, but it does not warn that reproducing the process will transmit prompts to third-party providers and consume quota or potentially billable resources. In a skill whose core purpose is probing many models across many keys, that omission materially increases the risk of unintentional external data disclosure and unexpected quota exhaustion.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The reproduction command directly encourages running probe scripts without disclosing that they will actively test external services at scale. Given this skill's router/probing context, users may trigger many live requests across multiple providers and keys, causing avoidable data exposure, rate-limit lockouts, or billing/quota consumption.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The installer accepts an API key as a positional command-line argument and later forwards it to `python3 ... --setup`, exposing the secret through shell history and potentially process listings (`ps`, `/proc`) while the command is running. API keys are high-value credentials, so even brief exposure can allow unauthorized API usage and quota theft.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The installer explicitly supports passing an API key as a positional argument (`bash install.sh <API_KEY>`), which can expose secrets through shell history, process listings, CI logs, and terminal recording. Because this skill is specifically designed to manage provider API keys for multiple LLM services, accidental disclosure of those credentials could allow unauthorized API use or quota exhaustion.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This code reads local API credentials and automatically sends authenticated probe requests to multiple third-party providers without any user confirmation, dry-run mode, or clear warning. In an agent-skill context, that is dangerous because simply invoking the skill can consume quota, reveal which providers the user has configured, and trigger unexpected external activity across several services.

Missing User Warnings

Low
Confidence
84% confidence
Finding
The script persists probing results to ~/ai_probe/results.json without any warning or disclosure, which can leave behind a record of available providers, models, response samples, and error text on disk. While the stored prompt is non-sensitive here, the file may still expose local environment details and service availability to other local users or later processes.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script transmits prompts and routing-related metadata to multiple third-party providers automatically, which can expose user or agent data to external services with different retention and policy regimes. In this skill context, the router is specifically designed to fan requests across several free-tier providers, which increases the data-sharing surface and makes silent transmission more dangerous than a single-provider client.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The script silently reads API keys from local credential stores and immediately uses them to contact multiple third-party providers. In an agent-skill context, undisclosed credential use and outbound requests can violate user expectations, trigger unintended quota consumption, and expose account metadata to external services without explicit consent.

Missing User Warnings

Low
Confidence
79% confidence
Finding
The script writes probe results to `~/ai_probe/ratelimits.json` without notice, creating a local artifact that reveals which providers, models, limits, and account behavior were observed. While it does not appear to store raw API keys, this telemetry can still disclose usage patterns and provider relationships to other local users or processes.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The router writes cached outputs to disk without any user-facing warning, and those outputs are derived from user prompts that may contain secrets, credentials, internal code, or regulated data. In agent workflows this is particularly risky because prompts commonly embed high-value context, making silent persistence a meaningful privacy and data-handling vulnerability.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This skill sends prompts and optional system instructions to third-party model providers across multiple vendors. In a security-sensitive agent context, that is dangerous when not clearly disclosed because users may unknowingly transmit secrets, source code, personal data, or internal instructions outside their trust boundary.

External Transmission

Medium
Category
Data Exfiltration
Content
txt, code, t = curl(url, ['Content-Type: application/json', f'X-goog-api-key: {k}'], body)
        else:
            cfg = {
             'mistral':    ('https://api.mistral.ai/v1/chat/completions',    creds('mistral')['api_key'], []),
             'openrouter': ('https://openrouter.ai/api/v1/chat/completions', creds('openrouter')['api_key'],
                            ['HTTP-Referer: https://arena.ai','X-Title: ArenaAgentMode']),
             'kilo':       ('https://api.kilo.ai/api/gateway/chat/completions', creds('kilo')['api_key'],
Confidence
96% confidence
Finding
https://api.mistral.ai/

External Transmission

Medium
Category
Data Exfiltration
Content
'mistral':    ('https://api.mistral.ai/v1/chat/completions',    creds('mistral')['api_key'], []),
             'openrouter': ('https://openrouter.ai/api/v1/chat/completions', creds('openrouter')['api_key'],
                            ['HTTP-Referer: https://arena.ai','X-Title: ArenaAgentMode']),
             'kilo':       ('https://api.kilo.ai/api/gateway/chat/completions', creds('kilo')['api_key'],
                            ['X-KILOCODE-FEATURE: arena-agent']),
             'cerebras':   ('https://api.cerebras.ai/v1/chat/completions',   creds('cerebras')['api_key'], []),
            }[prov]
Confidence
96% confidence
Finding
https://api.kilo.ai/

External Transmission

Medium
Category
Data Exfiltration
Content
['HTTP-Referer: https://arena.ai','X-Title: ArenaAgentMode']),
             'kilo':       ('https://api.kilo.ai/api/gateway/chat/completions', creds('kilo')['api_key'],
                            ['X-KILOCODE-FEATURE: arena-agent']),
             'cerebras':   ('https://api.cerebras.ai/v1/chat/completions',   creds('cerebras')['api_key'], []),
            }[prov]
            url, key, extra = cfg
            body = json.dumps({'model':model,'messages':[{'role':'user','content':PROMPT}],'max_tokens':2000})
Confidence
96% confidence
Finding
https://api.cerebras.ai/

External Transmission

Medium
Category
Data Exfiltration
Content
body=json.dumps({'contents':[{'parts':[{'text':q}]}],'generationConfig':{'maxOutputTokens':2500}})
    else:
        url,key,extra={
         'mistral':('https://api.mistral.ai/v1/chat/completions',creds('mistral')['api_key'],[]),
         'openrouter':('https://openrouter.ai/api/v1/chat/completions',creds('openrouter')['api_key'],
                       ['HTTP-Referer: https://arena.ai','X-Title: ArenaAgentMode']),
         'kilo':('https://api.kilo.ai/api/gateway/chat/completions',creds('kilo')['api_key'],
Confidence
92% confidence
Finding
https://api.mistral.ai/

External Transmission

Medium
Category
Data Exfiltration
Content
'mistral':('https://api.mistral.ai/v1/chat/completions',creds('mistral')['api_key'],[]),
         'openrouter':('https://openrouter.ai/api/v1/chat/completions',creds('openrouter')['api_key'],
                       ['HTTP-Referer: https://arena.ai','X-Title: ArenaAgentMode']),
         'kilo':('https://api.kilo.ai/api/gateway/chat/completions',creds('kilo')['api_key'],
                 ['X-KILOCODE-FEATURE: arena-agent']),
        }[prov]
        h=['Content-Type: application/json',f'Authorization: Bearer {key}']+extra
Confidence
92% confidence
Finding
https://api.kilo.ai/

External Transmission

Medium
Category
Data Exfiltration
Content
# request fail with "no credentials" — even when routing elsewhere.
            # Build only the provider we are actually calling.
            endpoints = {
              'mistral':    ('https://api.mistral.ai/v1/chat/completions', []),
              'openrouter': ('https://openrouter.ai/api/v1/chat/completions',
                             ['HTTP-Referer: https://arena.ai', 'X-Title: ArenaAgentMode']),
              'kilo':       ('https://api.kilo.ai/api/gateway/chat/completions',
Confidence
88% confidence
Finding
https://api.mistral.ai/

External Transmission

Medium
Category
Data Exfiltration
Content
'mistral':    ('https://api.mistral.ai/v1/chat/completions', []),
              'openrouter': ('https://openrouter.ai/api/v1/chat/completions',
                             ['HTTP-Referer: https://arena.ai', 'X-Title: ArenaAgentMode']),
              'kilo':       ('https://api.kilo.ai/api/gateway/chat/completions',
                             ['X-KILOCODE-FEATURE: arena-agent']),
              'cerebras':   ('https://api.cerebras.ai/v1/chat/completions', []),
            }
Confidence
88% confidence
Finding
https://api.kilo.ai/

Credential Access

High
Category
Privilege Escalation
Content
name: free-tier-ai-router
description: Quota-aware LLM router that squeezes maximum usable AI out of free-tier API keys across Gemini, Mistral, OpenRouter, Kilo and Cerebras. Probes every model on every key, measures real quality and real published rate limits, then routes each request to the cheapest model that can do the job — spending abundant capacity first and reserving scarce daily quota for when it is actually needed. Persists cooldowns to disk so a 429 discovered in one process is respected by the next. Use when an agent must make many LLM calls on free keys without hitting rate limits, when "all models failed", or when deciding which of several provider keys to use for a task.
version: 2.1.0
metadata: {"openclaw":{"emoji":"🎛️","requires":{"bins":["curl","python3"]},"configPaths":["~/.config/gemini/credentials.json","~/.config/mistral/credentials.json","~/.config/openrouter/credentials.json","~/.config/kilo/credentials.json","~/.cache/ai_router/state.json"],"network":{"outbound":["generativelanguage.googleapis.com","api.mistral.ai","openrouter.ai","api.kilo.ai","api.cerebras.ai"]}}}
---

# 🎛️ free-tier-ai-router
Confidence
95% confidence
Finding
credentials.json

Credential Access

High
Category
Privilege Escalation
Content
name: free-tier-ai-router
description: Quota-aware LLM router that squeezes maximum usable AI out of free-tier API keys across Gemini, Mistral, OpenRouter, Kilo and Cerebras. Probes every model on every key, measures real quality and real published rate limits, then routes each request to the cheapest model that can do the job — spending abundant capacity first and reserving scarce daily quota for when it is actually needed. Persists cooldowns to disk so a 429 discovered in one process is respected by the next. Use when an agent must make many LLM calls on free keys without hitting rate limits, when "all models failed", or when deciding which of several provider keys to use for a task.
version: 2.1.0
metadata: {"openclaw":{"emoji":"🎛️","requires":{"bins":["curl","python3"]},"configPaths":["~/.config/gemini/credentials.json","~/.config/mistral/credentials.json","~/.config/openrouter/credentials.json","~/.config/kilo/credentials.json","~/.cache/ai_router/state.json"],"network":{"outbound":["generativelanguage.googleapis.com","api.mistral.ai","openrouter.ai","api.kilo.ai","api.cerebras.ai"]}}}
---

# 🎛️ free-tier-ai-router
Confidence
95% confidence
Finding
credentials.json

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal

Static analysis

No suspicious patterns detected.