Back to skill

Security audit

cn-llm-router

Security checks across malware telemetry and agentic risk

Overview

The skill is broadly a legitimate LLM router, but its documentation under-discloses important prompt retention and network behaviors.

Review before installing if you will route confidential code, personal data, credentials, or regulated content. Use --no-cache for sensitive prompts, clear ~/.cn_llm_router cache data regularly, avoid arena voting with sensitive prompts, verify any update_url or wecom_webhook you configure, and treat the offline/mock claims as incomplete.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (16)

eval() call detected

High
Category
Dangerous Code Execution
Content
response = "def solution():\n    return 'mock answer'"
            else:
                response = _call_adapter(adapter, model_name, case["prompt"])
            if response and eval(case["check"])(response):
                correct += 1
        except Exception:
            pass
Confidence
97% confidence
Finding
This is a true code-execution risk: eval() turns a string into executable Python code. Although the current check strings are hardcoded in this file, the pattern is dangerous because any future refactor, externalized test case source, or compromised modification of CODE_CASES would allow arbitrary code execution during calibration. In a router skill that already handles external configs and model metadata, this becomes more concerning because calibration may be run in developer environments with access to API keys and local files.

eval() call detected

High
Category
Dangerous Code Execution
Content
response = "这是一个关于该主题的摘要,内容简洁且有意义。"
            else:
                response = _call_adapter(adapter, model_name, case["prompt"])
            if response and eval(case["check"])(response):
                correct += 1
        except Exception:
            pass
Confidence
97% confidence
Finding
This is the same unsafe pattern in the long-summary test path: eval() executes Python contained in case["check"]. Even if the current data is static, the construct creates an unnecessary remote-code-execution primitive if test cases are ever loaded from YAML/JSON, generated, or edited by an attacker or untrusted contributor. Because this script may run locally with filesystem and environment access, exploitation could expose secrets or modify project files.

Tp4

High
Category
MCP Tool Poisoning
Confidence
84% confidence
Finding
The documentation overstates and understates behavior in ways that can mislead users about what data is processed, what features exist, and what external actions occur. Security decisions depend on accurate capability disclosure; hidden benchmark/calibration writes, webhook pushes, health checks, or overstated multimodal/audio support can cause users to expose data or enable functions under false assumptions.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The module is presented as a local cost and usage tracker, but it also creates an arena_sessions table that stores full prompt text. Persisting raw prompts can capture secrets, personal data, proprietary source code, or regulated content, expanding the data exposure surface beyond what users would reasonably expect from billing telemetry. The risk is local rather than remote, but compromise of the workstation, backups, or shared user profile would expose sensitive prompt contents.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
共享 HTTP 辅助函数 `http_post_json()` 接受任意 URL,代码本身没有校验 `https://` scheme,和模块注释中“所有适配器只通过 https 调用”的安全承诺不一致。如果上层配置、适配器实现或后续维护中传入了 `http://` 或其他非预期 scheme,可能导致明文传输、请求被劫持,进而泄露 API Key、提示词或模型响应内容。该技能是多厂商 LLM 路由器,会集中处理多家模型凭据与敏感业务数据,因此这一缺口在此上下文中更危险。

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The module documentation explicitly promises 'zero networking', but the optional embedding path initializes a sentence-transformers model that may download model artifacts from the network on first use or when the model is not already cached locally. In a security-sensitive skill marketed as offline/local-only, this mismatch can mislead users into exposing prompts or triggering unexpected outbound connections, violating trust and offline assumptions.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The arena vote logging function persists the full user prompt into local SQLite, which can capture sensitive content such as secrets, personal data, or proprietary prompts unrelated to cost tracking. In this skill context, a router may handle arbitrary user inputs across many providers, so retaining raw prompts materially increases privacy and data-retention risk even without network exfiltration.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The docstring explicitly promises that mock mode is strictly isolated from real API paths and will not touch the network, but the module contains active outbound reachability checks via urllib in check_network/_ping_host_real. This mismatch can cause developers to enable mock mode in environments assumed to be offline or privacy-safe, yet still generate external traffic and leak metadata such as provider interest, host reachability, and execution timing.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The header states the feature supports full offline end-to-end mock execution with no network or keys required, but the implementation performs real HTTPS HEAD requests to multiple provider domains. In security-sensitive or air-gapped development environments, this breaks the offline guarantee and may trigger policy violations, unintended egress, or misleading trust assumptions about the safety of using the mock subsystem.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill describes `chat` usage but does not prominently warn that prompts and piped file/stdin content are transmitted to third-party model providers. Users may paste confidential code, documents, or regulated data believing processing is local except for explicit key usage, leading to unintended data disclosure.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The cache persists normalized user prompts and full model responses to a local SQLite database in the user's home directory without any consent, opt-in gate, masking, or content sensitivity checks. In an LLM router context, prompts and responses can easily contain secrets, personal data, source code, credentials, or regulated business content, so local persistence increases confidentiality risk if the host is shared, backed up, synced, or later accessed by other software or users.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The log_arena_vote function inserts the full prompt into local SQLite without minimization, warning, or consent flow. In the context of an LLM router, prompts commonly contain API keys, credentials, internal documents, customer data, or source code, so storing them verbatim creates a meaningful confidentiality risk even without network access. This skill context makes the issue more dangerous because the tool aggregates many provider workflows, increasing the likelihood that sensitive, high-value prompts pass through it.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill documents persistent logging of every model call to a local SQLite database, including vendor, model, task, token counts, cost, latency, and success state, but does not mention retention limits, access controls, or privacy warnings. In a router handling arbitrary user prompts, even metadata and task labels can reveal sensitive usage patterns, and implementations often expand such logs to include prompt/response content or identifiers over time.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The document states that budget alerts may be sent through enterprise messaging or cloud-linked channels without warning that operational metadata may leave the local system. Even if the payload is limited to spend or failure information, it can disclose usage volume, model vendors, timing, and organizational activity patterns to external services, which is sensitive in enterprise environments.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The native OAuth2 fallback constructs the token request by embedding the client ID and client secret directly in the URL query string. Even over HTTPS, secrets in URLs are more likely to be exposed through logs, monitoring systems, proxy access logs, browser/history tooling, error messages, and diagnostics than secrets sent in a request body or Authorization header. In this skill context, the code is an LLM router handling multiple provider credentials, so accidental secret leakage increases operational risk and could expose access to the downstream ERNIE account.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The code stores full user prompts in arena_sessions without any visible warning, minimization, or consent mechanism. Because this router is designed to process general-purpose LLM requests, prompts may include credentials, personal information, internal code, or business data, making silent local persistence a real privacy/security issue.

VirusTotal

65/65 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
_core/calibrate.py:97