Back to skill

Security audit

Mixture of Agents

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed OpenRouter multi-model analysis helper, with privacy and dependency caveats but no evidence of hidden persistence, local data harvesting, or destructive behavior.

Install only if you are comfortable sending prompts and model responses to OpenRouter-hosted models and using an OpenRouter API key. Avoid submitting secrets, regulated data, or confidential material unless that provider flow is approved, remove or avoid prompt-prefix logging in sensitive environments, and pin or vendor the axios dependency before production use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

T09 · Insecure Skill Coding Practices

Note
Location
scripts/moa.js:43
Finding

User Prompt Content Exposed in Process Logs

Content
View full analysis

Vulnerability Details

File Location: scripts/moa.js:43-44; equivalent behavior also occurs at scripts/moa-paid.js:21-22
Vulnerability Type: Sensitive data exposure through logging
Risk Level: Low

Complete Code Snippet

From scripts/moa.js:43-44:

javascript
console.log(`[MoA] Tier: ${tier.toUpperCase()} | Models: ${proposers.length}`);
console.log(`[MoA] Prompt: "${prompt.substring(0, 60)}..."\n`);

Equivalent code from scripts/moa-paid.js:21-22:

javascript
console.log(`[MoA-Paid] Querying 3 models: Kimi 2.5, MiniMax 2.5, GLM 5...`);
console.log(`[MoA-Paid] Prompt: "${prompt.substring(0, 80)}..."\n`);

Technical Analysis

Both implementations write a portion of the submitted prompt to standard output. Prompts may contain source code, confidential business information, personal data, credentials, access tokens, or other sensitive material.

Standard output is frequently captured by terminal scrollback, CI/CD systems, process supervisors, container platforms, centralized logging services, or host-agent logs. Consequently, data intentionally supplied for remote model processing is also copied into an additional storage and disclosure channel. Logging prompt contents is not required for the declared multi-model synthesis functionality and exceeds the minimum diagnostic data needed to operate the Skill.

The exposure is limited to the first 60 characters in moa.js and the first 80 characters in moa-paid.js, but secrets and identifying information can occur within those prefixes.

Attack Path

  1. A user invokes the Skill with a prompt containing confidential or sensitive information near its beginning.
  2. The Skill executes the relevant console.log statement before making the model requests.
  3. The prompt prefix is written to standard output.
  4. A shell, process manager, CI system, container runtime, or centralized logging platform records that output.
  5. A person ...[truncated 757 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove prompt-content logging from both scripts.
  • Log only non-sensitive operational metadata, such as the selected tier, model count, request identifier, success count, and elapsed time.
  • If prompt logging is required for debugging, place it behind an explicit opt-in debug setting that is disabled by default.
  • Apply secret and personal-data redaction before any debug output is emitted.
  • Document that diagnostic logs must not contain model prompts or responses.
  • Configure deployment environments to limit log access, retention, and forwarding as defense in depth.

A safer implementation would be:

javascript
console.log(`[MoA] Tier: ${tier.toUpperCase()} | Models: ${proposers.length}`);
console.log('[MoA] Processing request');

T08 · Insecure Dependencies

Note
Location
scripts/moa.js:1
Finding

Undeclared and Unpinned Axios Runtime Dependency

Content
View full analysis

Vulnerability Details

File Location: scripts/moa.js:1, scripts/moa-paid.js:1, and manifest.json:18-21
Vulnerability Type: Uncontrolled third-party dependency resolution
Risk Level: Low

Complete Code Snippet

Both JavaScript files import Axios without a corresponding package declaration or lockfile:

javascript
const axios = require('axios');

The manifest declares only the environment and runtime requirements:

json
"requires": {
  "env": ["OPENROUTER_API_KEY"],
  "runtime": "node >= 18"
},

The audited project contains no package.json or dependency lockfile specifying an approved Axios version.

Technical Analysis

Node.js resolves require('axios') from the available module search path. Because the project does not declare Axios in a package.json and does not provide a lockfile, a clean and reproducible dependency installation is unavailable.

This creates two security-relevant conditions:

  1. Operators may perform an ad hoc installation of the latest or an otherwise unreviewed Axios release.
  2. Execution may resolve an ambient axios package supplied by a parent project or global deployment environment rather than a version reviewed with this Skill.

A malicious or compromised resolved package can execute JavaScript when loaded by require. At that point, it runs inside the Skill process and can access the process environment, including OPENROUTER_API_KEY, as well as any files and network resources available to that process.

The reviewed files do not themselves install a malicious package, identify an unsafe registry, or contain a typosquatted dependency name. Exploitation therefore depends on an attacker influencing the package installation or Node module-resolution environment.

Attack Path

  1. A user installs or invokes the Skill in an environment where Axios is absent.
  2. The missing dependency causes the user or deployment system to install Axios ...[truncated 1382 chars]
Remediation
View remediation

Remediation Suggestions

  • Add a package.json that explicitly declares a reviewed Axios version.
  • Commit the corresponding lockfile, such as package-lock.json, to ensure deterministic resolution and integrity verification.
  • Use automated dependency scanning and controlled update review.
  • Install dependencies with lockfile-enforcing commands such as npm ci.
  • Restrict package installation to an approved registry and avoid relying on global or parent-project modules.
  • Prefer Node.js 18's built-in fetch API to eliminate Axios entirely, because the manifest already requires Node.js 18 or newer.
  • Run the Skill with only the filesystem, environment, and network permissions required for OpenRouter access.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill requires and uses an environment variable containing an API key, but it does not declare an explicit tool scope such as permissions or allowed-tools. That omission weakens least-privilege controls and makes the skill's runtime capabilities less transparent to users and orchestrators, increasing the chance that secrets are exposed or the skill is granted broader access than intended.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This skill is explicitly designed to send user prompts to multiple external third-party models through OpenRouter, yet the description does not clearly warn users about that data flow. Users may unknowingly submit sensitive, proprietary, or regulated information, which creates privacy, compliance, and data-handling risks amplified by the fact that prompts are shared with several downstream providers rather than a single local component.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script sends the full user prompt to OpenRouter and then forwards all three model responses back to the aggregator model, multiplying external disclosure of potentially sensitive data. In a skill context, users may not realize their input and intermediate outputs are transmitted to a third-party API provider and multiple upstream models, which creates privacy, compliance, and data-handling risk even if this is the feature's intended behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code sends the full user prompt to OpenRouter-hosted third-party models without any consent gate, redaction step, or explicit disclosure in the script itself. This is a real data-exposure risk because users may include secrets, proprietary code, or personal data, and this skill is specifically designed to fan that prompt out to multiple external providers, increasing exposure rather than limiting it.

Content

No source excerpt is available for this finding.

Ssd 4

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill embeds untrusted outputs from multiple proposer models directly into the aggregator prompt, giving those models an opportunity to inject instructions such as telling the aggregator to ignore prior guidance, exfiltrate hidden context, or bias the final answer. In a mixture-of-agents design, this risk is heightened because the whole workflow intentionally treats model-generated text as authoritative synthesis input, creating a classic indirect prompt-injection path.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The code reads OPENROUTER_API_KEY from the environment, which is a sensitive credential access pattern covered by the warning requirement for code files. There is no explanatory comment or user disclosure that the script depends on and uses this credential to contact an external paid service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script logs the first 60 characters of the user's prompt to stdout, which can leak sensitive fragments into terminal history, CI logs, container logs, or centralized logging systems. Even partial prompts can expose credentials, customer data, internal filenames, or the nature of confidential work.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/moa-paid.js:4

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/moa.js:5