Back to skill

Security audit

WeryAI Task Inspector

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly behaves like a read-only WeryAI task checker, but it includes under-documented account balance code and can send the API key to a custom server if an environment variable is set.

Review this skill before installing. It appears intended for read-only WeryAI task inspection, but only use it in an environment where WERYAI_BASE_URL cannot be attacker-controlled, and be aware the package contains account balance lookup code that is not part of the documented task-inspection workflow.

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

Warning
Location
scripts/task-inspector.js:33
Finding

Unvalidated API Base URL Can Expose the WeryAI Bearer Credential

Content
View full analysis

Vulnerability Details

File Location: scripts/task-inspector.js:33-38 and scripts/vendor/weryai-core/client.js:4-17, 38-43
Vulnerability Type: Unvalidated credential destination
Risk Level: Medium

Vulnerable Code

js
function createContext(verbose) {
  return {
    apiKey: process.env.WERYAI_API_KEY || '',
    baseUrl: process.env.WERYAI_BASE_URL || 'https://api.weryai.com',
    verbose,
    requestTimeoutMs: Number(process.env.WERYAI_REQUEST_TIMEOUT_MS) || 30_000,
  };
}
js
export function createClient(ctx) {
  const { apiKey, baseUrl, requestTimeoutMs, verbose } = ctx;

  async function request(method, path, body = null, { retries = 0 } = {}) {
    if (!apiKey) {
      throw Object.assign(
        new Error('Missing API key environment variable.'),
        { code: 'NO_API_KEY' },
      );
    }

    const url = `${baseUrl}${path}`;
    const headers = {
      Authorization: `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
    };

    // ...

    const res = await fetch(url, {
      method,
      headers,
      body: body ? JSON.stringify(body) : undefined,
      signal: controller.signal,
    });

Technical Analysis

The client accepts WERYAI_BASE_URL from the process environment and uses it directly to construct the request destination. It does not parse or validate the URL, require HTTPS, or verify that the hostname belongs to the official WeryAI service.

The same request unconditionally attaches WERYAI_API_KEY as an Authorization: Bearer header. Consequently, control over WERYAI_BASE_URL is equivalent to control over the destination receiving the credential.

This behavior also weakens the documented trust boundary that the skill uses official WeryAI endpoints. Although exploitation requires influence over the runtime environment, environment variables may be supplied through wrappers, automation configuration, container settings, or inherited shell state.

Attack Path

  1. An attacker gain ...[truncated 1176 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove the WERYAI_BASE_URL override if custom API origins are not a supported requirement.
  2. If an override is required, parse it with new URL() and reject malformed values.
  3. Require the https: protocol.
  4. Allowlist the exact official hostname or a narrowly defined set of trusted WeryAI hostnames.
  5. Reject embedded credentials, unexpected ports, fragments, and non-root path prefixes unless explicitly required.
  6. Validate the final request URL again immediately before attaching the bearer header.
  7. Attach Authorization only when the final URL matches the trusted origin.
  8. Fail closed with a clear configuration error when validation fails.
  9. Add automated tests covering attacker-controlled domains, HTTP URLs, deceptive subdomains, user-information syntax, and unexpected ports.

Example hardening:

js
const OFFICIAL_ORIGIN = 'https://api.weryai.com';

function validateBaseUrl(value) {
  const url = new URL(value);

  if (url.origin !== OFFICIAL_ORIGIN) {
    throw new Error('WERYAI_BASE_URL must use the official WeryAI API origin.');
  }

  if (url.username || url.password || url.search || url.hash) {
    throw new Error('Invalid WERYAI_BASE_URL.');
  }

  return url.origin;
}
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

A description-behavior mismatch is dangerous because users and orchestrators may trust the skill to perform read-only task inspection while the implementation reportedly does something unrelated: retrieving account balance/credits. That can expose sensitive billing information, violate least surprise, and cause downstream agents to make incorrect decisions based on false assumptions about what data was queried.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises network access and use of an API key via metadata, but it does not declare an explicit tool scope such as allowed-tools or permissions. That creates an authorization and review gap: consumers and policy systems cannot easily verify or constrain which capabilities the skill may exercise, increasing the chance of unintended data access or network use.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes a skill for inspecting, querying, summarizing, and debugging WeryAI task IDs and batch IDs, including extracting artifacts from existing tasks. This code instead calls a generation balance endpoint to retrieve account credits, which is an account-level capability not mentioned in the task/batch inspection description.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.