Back to skill

Security audit

Outreach List Builder

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed LinkedIn prospect-list helper that uses Veezee APIs and does not show hidden, destructive, or deceptive behavior.

Before installing, confirm you are comfortable sending prospecting criteria and LinkedIn lookup requests to Veezee, and prefer MCP authorization or a pinned/reviewed SDK version over running an unpinned npx command. Treat the stored Veezee API key like a credential.

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

T08 · Insecure Dependencies

Warning
Location
SKILL.md:14
Finding

Unpinned Third-Party Package Execution Through npx

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, line 14
Vulnerability Type: Supply-chain risk caused by unpinned package execution
Risk Level: Medium

Complete Code Snippet:

markdown
- SDK: `import { VeezeeClient } from "@veezee/sdk"`; `const client = new VeezeeClient(); await client.mint();` mints and stores the free key the first time and reuses it on later runs. Platform methods live on the namespace (`client.linkedin.getProfile/searchPeople/getCompany/getPosts`); `client.resolveUrl` and `client.getUsage` are top-level. The client sends retries and Idempotency-Keys for you. The `veezee` CLI (`npx @veezee/sdk init`) mints and stores the same key.

Technical Analysis

The skill instructs the user or Agent to run npx @veezee/sdk init without pinning the dependency to a specific audited version. Depending on the local npm and npx configuration, this command may download and immediately execute the package version currently resolved from the configured npm registry.

The project provides no exact version, package-lock file, integrity hash, checksum-verification procedure, or source-review requirement. Consequently, the code executed at installation time can differ from the code that existed when the skill was audited. Exploitation would require compromise or malicious control of the package, its publisher account, a dependency, or the configured package registry.

Attack Path

  1. An attacker compromises the @veezee/sdk publishing account, package supply chain, or package registry used by the victim.
  2. The attacker publishes or serves a malicious package version containing an installation-time or CLI payload.
  3. A user or Agent follows the skill instructions and runs npx @veezee/sdk init.
  4. npx resolves and downloads the unpinned package version.
  5. The malicious package executes with the privileges of the invoking user.
  6. The payload may access files, environment variables, Agent co ...[truncated 593 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace the unversioned command with an exact, audited package version, such as npx --package=@veezee/sdk@<approved-version> veezee init.
  • Manage the dependency through a committed lockfile containing registry-resolved integrity metadata.
  • Install dependencies in a separate verification step and use npm ci rather than resolving the latest available release during skill execution.
  • Verify package provenance, publisher identity, signatures or attestations, and integrity hashes before execution.
  • Run initialization in a least-privileged, isolated environment with access only to the files and credentials required for the task.
  • Document where the minted API key is stored and require restrictive file permissions or an operating-system credential store.
  • Establish a controlled upgrade process in which new SDK versions are reviewed and tested before the pinned version is changed.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The description says to use the skill whenever the user wants prospects, leads, a target-account list, people to sell to, or personalized outreach angles, even if they only describe the buyer. This is a broad activation scope with limited negative examples, which could cause unintended invocation for general sales-assistance requests that are not specifically asking for LinkedIn prospect list building.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The skill instructs the agent to send user-supplied search criteria and prospect-enrichment queries to external Veezee endpoints, which is a real external data transmission path. In this context, user prompts may contain sensitive commercial targeting data, account lists, or internal sales strategy, and the skill does not require explicit user confirmation or data-minimization before transmitting that information off-platform.

Content

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

md
Every call needs an API key. Minting one is free and human-free: no signup, no card. A call without a key fails with `KEY_REQUIRED` (401) carrying `mint_url`; the fix is the free mint below, never a payment. Two equivalent surfaces; pick whichever your environment has:

- MCP: add the server `https://mcp.veezee.io/linkedin` (streamable-http; `https://mcp.veezee.io/all` exposes every tool). Hosts that support MCP authorization (Claude Code, claude.ai) open a Veezee sign-in on connect (email code, no password): that is the whole auth step. Other hosts: mint a key with `POST https://api.veezee.io/v1/keys/mint` (empty body; the key is shown once) and put it in the connection's `Authorization: Bearer` header.
- SDK: `import { VeezeeClient } from "@veezee/sdk"`; `const client = new VeezeeClient(); await client.mint();` mints and stores the free key the first time and reuses it on later runs. Platform methods live on the namespace (`client.linkedin.getProfile/searchPeople/getCompany/getPosts`); `client.resolveUrl` and `client.getUsage` are top-level. The client sends retries and Idempotency-Keys for you. The `veezee` CLI (`npx @veezee/sdk init`) mints and stores the same key.

A fresh `vz_trial_` key runs under a free per-IP daily budget of 200 credits, cached data only, search capped at 10 results per call, first page only on any cursor sequence. That covers a handful of prospects at most; a list built at real volume, with enrichment and company context per prospect, needs purchased credits. When the budget or a trial cap runs out (`TRIAL_CAP_EXCEEDED`, `INSUFFICIENT_CREDITS`, `BUDGET_EXHAUSTED`), the error carries `upgrade_url` and a machine-readable `offer`: hand that link to your human; purchases credit the same key directly, nothing to reconfigure.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.