Back to skill

Security audit

Magic Quill

Security checks for vulnerabilities and agentic risk

Overview

This skill generally does what it claims, but it fetches broad arbitrary URLs and documents unpinned installs, so it belongs in Review before use.

Before installing, prefer a pinned audited commit or release instead of the floating npx commands. Use this only with trusted public topics or URLs, avoid localhost, intranet, cloud metadata, or credential-bearing pages, keep --out under spells/, and review the separate spellbook hook before installing it.

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

Error
Location
scripts/generate-spell-mapping.mjs:1576
Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate-spell-mapping.mjs`, lines 512–516, 639–655, 1576–1581, and 2057–2059 **Vulnerability Type**: Server-Side Request Forgery through user-provided, discovered, and redirected URLs **Risk Level**: High ### Vulnerable Code ```js if (token === "--url") { args.url = String(argv[index + 1] ?? "").trim(); index += 1; continue; } ``` ```js function canonicalizeReferenceUrl(value) { try { const url = new URL(String(value).trim()); if (!/^https?:$/i.test(url.protocol)) { return ""; } url.hash = ""; if (url.pathname !== "/") { url.pathname = url.pathname.replace(/\/+$/g, "") || "/"; } return url.toString(); } catch { return ""; } } ``` ```js const response = await fetch(reference.url, { headers: { accept: "application/json,text/html,application/xhtml+xml;q=0.9,*/*;q=0.8", "user-agent": USER_AGENT } }); ``` ```js async function fetchLoreFromUrl(url) { const html = await fetchText(url); const title = extractTitle(html); const description = extractMeta(html, "property", "og:description") || extractMeta(html, "name", "description"); const bodyText = stripHtmlToText(html).slice(0, 12000); return { mode: "url", source: url, title, summary: description, text: [title, description, bodyText].filter(Boolean).join("\n\n") }; } ``` ### Technical Analysis The `--url` argument accepts any URL that can be parsed by the standard `URL` constructor. The later canonicalization logic only restricts the protocol to HTTP or HTTPS. It does not reject: - Loopback destinations such as `127.0.0.1` and `[::1]` - Private network ranges - Link-local addresses - Cloud instance metadata services - Internal DNS names - DNS names that resolve or rebind to restricted addresses The generator directly fetches the supplied URL both as a spell-list candidate and as a lore source. It also fetches URLs discovered through search ...[truncated 2094 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Restrict network destinations** - Maintain an allowlist of trusted public origins needed for the declared functionality. - Require explicit opt-in before fetching arbitrary user-provided origins. - Do not infer or follow cross-origin endpoints unless separately approved. 2. **Validate resolved addresses** - Resolve hostnames before connecting. - Reject IPv4 and IPv6 loopback, private, link-local, multicast, reserved, and unspecified ranges. - Explicitly block cloud metadata destinations, including `169.254.169.254`. - Protect against DNS rebinding by validating the address actually used for each connection. 3. **Control redirects** - Use `redirect: "manual"`. - Resolve and validate every redirect destination before issuing the next request. - Apply a small redirect limit and reject HTTPS-to-HTTP downgrades. 4. **Limit resource use** - Add an `AbortController` timeout to every network request. - Enforce maximum response sizes before calling `text()` or parsing JSON. - Restrict content types to those necessary for spell-list and lore processing. 5. **Constrain discovery** - Prefer same-origin links. - Remove speculative endpoint probing for untrusted hosts. - Provide a heuristic-only or offline mode and make it the default where network discovery is unnecessary. 6. **Prevent indirect disclosure** - Avoid incorporating arbitrary remote response text into output without strict validation. - Do not include internal URLs in generated comments or diagnostic output. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:65
Finding
Installation Instructions Use Mutable, Unpinned Remote Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 65–66 and 74–79 **Vulnerability Type**: Unpinned package and repository installation sources **Risk Level**: Medium ### Vulnerable Code ```bash npx skills add wynnsu/openclaw-spellbook/magic-quill ``` ```bash # Install the spellbook hook (includes magic-quill skill) npx skills add wynnsu/openclaw-spellbook ``` ```bash npx skills add wynnsu/openclaw-spellbook/hooks/spellbook ``` ### Technical Analysis The documented installation commands invoke `npx skills` without specifying an audited package version. They also identify repository content through mutable repository paths rather than immutable commit hashes or verified release tags. As a result, the content resolved when a user follows these commands can differ from the content covered by this audit. If the package registry account, upstream repository, release process, or transitive dependency chain is compromised, the installation command could retrieve and execute changed code. The reviewed project itself does not import third-party runtime packages and no malicious dependency was found in the provided artifact. This finding concerns the mutable installation procedure documented in `SKILL.md`. ### Attack Path 1. An attacker compromises the package publishing account, upstream repository, or another mutable source used by the installation flow. 2. The attacker publishes or inserts a modified `skills` package, Skill, hook, or related installer component. 3. A user follows one of the documented unpinned `npx skills add` commands. 4. `npx` resolves the currently available package rather than the version reviewed during this audit. 5. The installation process retrieves the currently referenced repository content. 6. The substituted installer or Skill code executes with the privileges of the user running the command. ### Impact Assessment Impact depends on the behavior of the substituted package or repository content. Because insta ...[truncated 616 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the `skills` CLI to a specific audited version, for example by using an exact package version rather than the latest registry resolution. 2. Pin the repository source to an immutable commit SHA or a signed, immutable release. 3. Publish and document integrity hashes where the installation mechanism supports them. 4. Verify release signatures and checksums before installation. 5. Avoid installer lifecycle scripts where possible, or document and inspect every script that will execute. 6. Document the exact package version, repository commit, and dependency versions covered by the security review. 7. Use lockfiles and reproducible installation procedures for any packaged distribution. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Content
delete: "Scuttle",
        deploy: "Set Sail",
        fix: "Patch",
        monitor: "Spyglass",
        default: "Crew"
      },
      objects: {
        web: "the Horizon",
        file: "the Captain's Log",
        code: "the Map",
        process: "the Cannons",
        repo: "the Hold",
        task: "the Voyage",
        default: "the Voyage"
      },
      icons: {
        default: "🏴‍☠️",
        deploy: "⛵",
        monitor: "🔭"
      },
      suffixes: ["Kraken", "Reef", "Tempest", "Harbor", "Treasure"]
    }
  },
  {
    match: /(marvel|dc\b|avengers|x-men|superhero|batman|superman|spider-man|iron\s*man)/i,
    profile: {
      id: "superhero",
      verbs: {
        search: "Detect",
        read: "Brief",
        write: "Draft",
        create: "Assemble",
        fix: "Stabilize",
        debug: "Expose",
        deploy: "Launch",
        kill: "Neutralize",
        default: "Activate"
      },
      objects: {
        web: "the Network",
        file: "t
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding
The skill instructs users to run `npx skills add ...` without pinning a specific package version, which can cause execution of whatever package version is current at install time. If the upstream package or dependency chain is compromised, users may unknowingly execute malicious code during installation or receive altered behavior later.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding
This line again references `npx skills add` with an unpinned source, so the install target can change over time and may resolve to a compromised or unexpected package state. Because `npx` executes fetched code, this creates a supply-chain exposure rather than a merely informational issue.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding
The installation command uses `npx skills add wynnsu/openclaw-spellbook` without any version pinning, so consumers will retrieve the latest state of that package/repository at execution time. In a skill that already performs dynamic fetching and writes files, supply-chain compromise would increase the chance of delivering harmful code or instructions through a trusted workflow.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding
This command points `npx skills add` at a repo subpath without pinning an immutable revision, leaving the fetched code subject to upstream changes or compromise. Since `npx` may download and execute code immediately, an attacker controlling the source or its dependencies could gain code execution on the user's system.

External Transmission

Medium
Category
Data Exfiltration
Content
const endpoints = [
    "https://wry-manatee-359.convex.site/api/v1/skills",
    "https://clawhub.ai/api/v1/skills",
    "https://api.clawhub.ai/v1/skills"
  ];

  let lastError = null;
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.