Back to skill

Security audit

МойСклад

Security checks for vulnerabilities and agentic risk

Overview

This MoySklad skill is mostly coherent, but it needs review because its low-level API command can send your ERP credential to an arbitrary web address.

Review before installing. Use a scoped bearer token rather than login/password, avoid the generic api command with full URLs, and consider fixing the helper so it only sends credentials to the official MoySklad API before using it with real business data.

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

Error
Location
scripts/moysklad.mjs:31
Finding

Arbitrary Credential Forwarding to Attacker-Controlled URLs

Content
View full analysis

Vulnerability Details

File Location: scripts/moysklad.mjs, lines 31–48; reachable through lines 267–274
Vulnerability Type: Credential disclosure through unrestricted authenticated network requests
Risk Level: High

Vulnerable Code

javascript
async function api(method, path, body) {
  const url = path.startsWith("http") ? path : `${BASE_URL}${path}`;
  const res = await fetch(url, {
    method,
    headers: {
      Authorization: getAuthHeader(),
      "Content-Type": "application/json",
      "Accept-Encoding": "gzip",
    },
    body: body !== undefined ? JSON.stringify(body) : undefined,
  });

  if (res.status === 204) return null;

  const data = await res.json();
  if (!res.ok) {
    const msg = data?.errors?.[0]?.error ?? res.statusText;
    throw new Error(`HTTP ${res.status}: ${msg}`);
  }
  return data;
}

The vulnerable function is exposed through the generic API command:

javascript
async function cmdApi(positional) {
  const [method, path, bodyStr] = positional;
  if (!method || !path) {
    console.error("Usage: api <METHOD> <path> [json-body]");
    process.exit(1);
  }
  const body = bodyStr ? JSON.parse(bodyStr) : undefined;
  const result = await api(method.toUpperCase(), path, body);
  out(result);
}

Technical Analysis

The generic api command accepts a user-controlled URL or path. In api(), any value beginning with http is treated as an absolute URL. The function then unconditionally attaches the MoySklad Authorization header returned by getAuthHeader().

Consequently, the authenticated request is not restricted to the declared MoySklad API origin. An attacker who can influence CLI arguments can direct a request to an arbitrary server and receive either:

  • The bearer token from MOYSKLAD_TOKEN; or
  • A reusable Basic Authentication value derived from MOYSKLAD_LOGIN and MOYSKLAD_PASSWORD.

...[truncated 2120 chars]

Remediation
View remediation

Remediation Suggestions

  1. Reject absolute, scheme-relative, and non-root-relative URLs. The generic command should accept only API paths beginning with /.

  2. Resolve the supplied path with the URL parser and validate the resulting destination before attaching credentials:

    javascript
    function buildApiUrl(path) {
      if (typeof path !== "string" || !path.startsWith("/") || path.startsWith("//")) {
        throw new Error("Only MoySklad API paths beginning with a single slash are allowed");
      }
    
      const url = new URL(path, `${BASE_URL}/`);
      const base = new URL(BASE_URL);
    
      if (
        url.protocol !== "https:" ||
        url.hostname !== base.hostname ||
        url.port !== "" ||
        !url.pathname.startsWith("/api/remap/1.2/")
      ) {
        throw new Error("External API destinations are not allowed");
      }
    
      return url;
    }
    
  3. Attach the Authorization header only after the final URL has passed the origin and path validation.

  4. Prefer removing arbitrary HTTP methods from the generic command or explicitly allow only methods required by the requested operation. Require confirmation for destructive methods such as DELETE.

  5. Disable automatic redirects where supported, or validate each redirect destination before forwarding authentication. Authentication must never be sent to another origin or downgraded to HTTP.

  6. Prefer scoped bearer tokens over reusable login/password credentials and grant the configured account only the minimum MoySklad permissions required.

  7. Add regression tests covering external HTTPS URLs, plain HTTP URLs, scheme-relative URLs, deceptive hostnames, alternate ports, encoded paths, and redirect attempts.

  8. Revoke and rotate any credential that may previously have been used with an untrusted absolute URL.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (56)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 32)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 39)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 42)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 45)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 48)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 51)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 54)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 57)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 65)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 68)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 69)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 70)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 71)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 74)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 75)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 76)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 79)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 80)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 81)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 84)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 87)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 88)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 89)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 92)May include surrounding context.

md
node scripts/moysklad.mjs me

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 93)May include surrounding context.

md
node scripts/moysklad.mjs me

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/moysklad.mjs:14