Back to skill

Security audit

Multi-Model Router

Security checks for vulnerabilities and agentic risk

Overview

This router is not clearly malicious, but it can automatically route supposedly private context to cloud models despite claiming sensitive data stays local.

Review before installing. This skill may be useful for model routing, but do not rely on its stated privacy guarantee for secrets, credentials, private documents, or sensitive workspace context unless the fallback behavior is changed to fail closed or require explicit consent for cloud routing.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/analyzer.js:25
Finding

Sensitive conversation context is excluded from privacy analysis

Content
View full analysis
32768) { reason = "large context requirement"; } else { reason = "general purpose routing"; } return { contextLength, privacyLevel, taskType, costSensitivity: requirements.costSensitive || false, performanceCritical: requirements.performanceCritical || false, reason }; } ``` ```js detectPrivacyLevel(prompt) { // Enhanced privacy detection with multiple checks const lowerPrompt = prompt.toLowerCase(); // Check for sensitive patterns const hasSensitivePattern = this.sensitivePatterns.some(pattern => pattern.test(prompt) ); // Check for common sensitive contexts const sensitiveContexts = [ 'my password is', 'api key', 'secret key', 'access token', 'authentication', 'login credentials' ]; const hasSensitiveContext = sensitiveContexts.some(ctx => lowerPrompt.includes(ctx) ); return (hasSensitivePattern || hasSensitiveContext) ? 'high' : 'low'; } ``` ### Technical Analysis The analyzer includes both the prompt and conversation context when estimating the total token count, but it passes only `prompt` to `detectPrivacyLevel`. Consequently, passwords, API keys, access tokens, personally identifiable information, private conversation history, and other confidential information contained exclusively in `context` do not affect the privacy classification. A harmless prompt combined with ...[truncated 1440 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/router-engine.js:42
Finding

Long privacy-sensitive input fails open to the configured cloud fallback

Content
View full analysis
32768) { candidates = this.applyContextFilter(candidates, analysis.contextLength); } // Apply cost optimization if requested if (analysis.costSensitivity || userPreferences.costSensitive) { candidates = this.applyCostOptimization(candidates); } // Apply performance priority if requested if (analysis.performanceCritical || userPreferences.performanceCritical) { candidates = this.applyPerformancePriority(candidates); } // Return the best candidate based on priority return this.selectBestCandidate(candidates); } ``` ```js applyPrivacyFilter(candidates) { return candidates.filter(model => this.config.models[model].privacy_level === 'local' ); } applyContextFilter(candidates, requiredContextLength) { return candidates.filter(model => this.config.models[model].context_window >= requiredContextLength ); } ``` ```js selectBestCandidate(candidates) { if (candidates.length === 0) { console.warn("No suitable models found, using fallback"); return this.config.fallback_strategy; } return candidates[0]; // Return highest priority candidate } ``` The only configured local model has a 32K context window: ```json "offline": { "alias": "ollama/qwen35-32k", "context_window": 32768, "privacy_level": "local", "cost_per_1k_input": 0, "cost_per_1k_output": 0, "priority": 3 } ``` Th ...[truncated 1746 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/router.js:37
Finding

Routing exceptions return unredacted context with a cloud model

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (12)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/analyzer.js (reported line 55)May include surrounding context.

js
// Use precise token counting for better accuracy
      const promptTokens = countTokens(prompt);
      const contextTokens = countTokens(context);
      return promptTokens + contextTokens;
    } catch (error) {
      // Fallback to character-based estimation
      console.warn("Token counting failed, using fallback method");

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/analyzer.js (reported line 77)May include surrounding context.

js
'my password is',
      'api key',
      'secret key', 
      'access token',
      'authentication',
      'login credentials'
    ];

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Documentation written entirely in Chinese without language choice can prevent some users from understanding routing behavior, privacy limitations, and consent-relevant details. In a skill that automatically decides whether data stays local or goes to the cloud, lack of accessible disclosure increases the risk of uninformed use and accidental exposure of sensitive data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill claims privacy protections and automatic routing, but it does not clearly warn users that some tasks may still be sent to cloud-hosted models when the system deems them non-sensitive. This can create a misleading privacy expectation, causing users to provide data they would not have shared if cloud routing had been explicitly disclosed.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest uses Chinese-language description text and Chinese trigger phrases alongside English ones, but it does not state that the skill is Chinese-specific or offer any user language choice. This creates a natural-language policy concern because the locale behavior appears implicit rather than explicitly documented or opt-in.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The activation contexts are broad and subjective, such as triggering when a user mentions multiple AI models or when privacy-sensitive content is detected. In a skill with access to memory and workspace files, overbroad activation increases the chance the router engages unexpectedly and influences model selection or data handling without clear user intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation presents privacy-sensitive routing as automatic protection without clearly warning that only some content will stay local and that other prompts may still be sent to cloud models. This can mislead developers into assuming broader confidentiality guarantees than actually exist, causing accidental disclosure of sensitive data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Automatic fallback to a cloud model can transmit prompts or context to a remote service when the primary route fails, but the documentation does not clearly disclose this behavior. In a privacy-focused router, undisclosed fallback materially increases the risk of sensitive data exfiltration because failures may trigger remote processing unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill persists user preferences to a local JSON file without any consent flow, disclosure, access control, or data-minimization safeguards. While the current fields look low sensitivity, preference data can still reveal privacy posture, usage patterns, or operational choices, and in a multi-user or shared-host environment the file may be readable by other local users or included in backups/logging workflows.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The task-type classifier relies entirely on Chinese keywords such as 总结, 分析, 代码, and 日常 to determine behavior. This creates an implicit language restriction in the skill logic without offering a user language choice or documenting that the skill is intentionally limited to Chinese-language inputs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code persistently writes routing metadata, including model choice, reason, context length, privacy level, and task type, to a local audit log without any evidence of user notice, consent, minimization, or retention controls. Even if the fields are not raw user content, they can still reveal sensitive behavioral and privacy-related information, and the danger is increased because the component explicitly records a 'privacyLevel' classification while storing it silently.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

When no candidate models remain after applying privacy and context filters, the router silently falls back to high_context, which is configured as a cloud model. For privacy-sensitive requests, this can route data off-device despite the earlier privacy check, creating an implicit privacy-boundary bypass with only a console warning and no user-facing consent or hard failure.

Content

No source excerpt is available for this finding.