registry  /  vercel  /  54.20.1

vercel@54.20.1

The command-line interface for Vercel

AI Security Review

scanned 9d ago · by lpm-firewall-ai

No confirmed malicious attack surface was found. The risky primitives are aligned with an authenticated Vercel CLI and are activated by user CLI commands, not package install or import.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
user runs vercel/vc CLI commands
Impact
package-aligned project/account operations; no credential harvesting or unconsented persistence identified
Mechanism
authenticated cloud CLI with optional update check, telemetry, curl helper, and user-invoked MCP setup
Rationale
Static inspection shows a legitimate Vercel CLI with no lifecycle hook and no install-time foreign agent/control-surface writes. Scanner hits for env, network, shell, and MCP are user-invoked CLI features and package-aligned endpoints rather than concrete attack behavior.
Evidence
package.jsondist/vc.jsdist/index.jsdist/commands-bulk.jsdist/get-latest-worker.cjsdist/fetch-dist-tags.cjs
Network endpoints6
api.vercel.comvercel.comregistry.npmjs.org/-/package/${name}/dist-tagstelemetry.vercel.com/api/vercel-cli/v1/eventsmcp.vercel.comskills.sh/api/search

Decision evidence

public snapshot
AI called this Clean at 93.0% confidence as Benign with low false-positive risk.
Evidence for block
    Evidence against
    • package.json has bin entries only and no npm lifecycle install hooks.
    • dist/vc.js is a CLI shim that handles --version/--help then imports dist/index.js.
    • dist/index.js reads VERCEL_TOKEN/auth config for authenticated CLI use and spawns only its bundled get-latest worker.
    • dist/fetch-dist-tags.cjs only queries npm registry dist-tags for update checks.
    • dist/commands-bulk.js network calls are Vercel CLI product APIs and telemetry endpoints.
    • dist/commands-bulk.js mcp command is explicitly user-invoked and configures Vercel MCP via prompts/deep links, not install-time mutation.
    Behavioral surface
    Source
    ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetworkShell
    Supply chain
    HighEntropyStringsMinifiedObfuscatedProtestwareTelemetryUrlStrings
    ManifestNo manifest risk signals triggered.
    scanned 125 file(s), 7.10 MB of source, external domains: 127.0.0.1, ai-gateway.vercel.sh, api.example.com, api.vercel.com, app.example.com, backend.internal, bitbucket.org, codeload.github.com, cursor.sh, dogs.are.great, err.sh, example.com, example.vercel.app, examples.vercel.sh, feross.org, fetch.spec.whatwg.org, gist.githubusercontent.com, github.com, gitlab.com, internal.example.com, mcp.vercel.com, mimesniff.spec.whatwg.org, mozilla.github.io, my-app-xxxxx.vercel.app, new-api.example.com, now.sh, openapi-internal.vercel.sh, openapi.vercel.sh, raw.githubusercontent.com, registry.npmjs.org, sites.google.com, stackoverflow.com, telemetry.vercel.com, tools.ietf.org, vercel.com, vercel.link, w3c.github.io, websockets.spec.whatwg.org, www.example.com, www.w3.org, your-project-abc123.vercel.app
    Oversized source lightweight scan
    dist/chunks/chunk-RB7WQKNC.js2.37 MB file, sampled 256 KB
    FilesystemNetworkChildProcessEnvironmentVarsEvalShellDynamicRequireHighEntropyStringsUrlStringsbitbucket.orgfeross.orggithub.comgitlab.comstackoverflow.comtools.ietf.orgvercel.comvercel.linkwww.w3.org

    Source & flagged code

    10 flagged · loading source
    dist/index.jsView file
    464import { dirname, parse as parsePath, resolve as resolvePath } from "path"; L465: import { spawn } from "child_process"; L466: var import_fetch_dist_tags = __toESM(require_fetch_dist_tags(), 1);
    High
    Child Process

    Package source references child process execution.

    dist/index.jsView on unpkg · L464
    2Cross-file remote execution chain: dist/index.js spawns dist/chunks/chunk-JDO6BSKN.js; helper contains network access plus dynamic code execution. L2: import { fileURLToPath as __fileURLToPath } from 'node:url'; L3: import { dirname as __dirname_ } from 'node:path'; L4: const require = __createRequire(import.meta.url); ... L118: if (stream == null) L119: stream = process.stdout; L120: if (callback == null) ... L141: var paths = __require("path"); L142: var isWinOS = /^win/i.test(process.platform); L143: function normalize_path(path2) { ... L188: const object = {}; L189: object.cache = () => process.env.XDG_CACHE_HOME || path2.join(osPaths.home() || osPaths.temp(), ".cache"); L190: object.config = () => process.env.XDG_CONFIG_HOME || path2.join(osPaths.home() || osPaths.temp(), ".config");
    High
    Cross File Remote Execution Context

    Source spawns a local helper that also contains network and dynamic execution context; review data flow before blocking.

    dist/index.jsView on unpkg · L2
    dist/commands-bulk.jsView file
    2import { fileURLToPath as __fileURLToPath } from 'node:url'; L3: import { dirname as __dirname_ } from 'node:path'; L4: const require = __createRequire(import.meta.url); ... L471: import { L472: require_execa L473: } from "./chunks/chunk-24FCBXI4.js"; ... L699: - Use AI Gateway for model routing, set AI_GATEWAY_API_KEY, using a model string (e.g. 'anthropic/claude-sonnet-4.6'), Gateway is already default in AI SDK L700: needed. Always curl https://ai-gateway.vercel.sh/v1/models first; never trust model IDs from memory L701: - For durable agent loops or untrusted code: use Workflow (pause/resume/state) + Sandbox; use Vercel MCP for secure infra access`; ... L790: telemetry2.trackCliFlagHelp("agent"); L791: output_manager_default.print(help(agentCommand, { columns: client.stderr.columns })); L792: return 2;
    Critical
    Credential Exfiltration

    Source appears to send environment or credential material to an external endpoint.

    dist/commands-bulk.jsView on unpkg · L2
    2Trigger-reachable chain: manifest.bin -> dist/vc.js -> dist/index.js -> dist/commands-bulk.js L2: import { fileURLToPath as __fileURLToPath } from 'node:url'; L3: import { dirname as __dirname_ } from 'node:path'; L4: const require = __createRequire(import.meta.url); ... L471: import { L472: require_execa L473: } from "./chunks/chunk-24FCBXI4.js"; ... L699: - Use AI Gateway for model routing, set AI_GATEWAY_API_KEY, using a model string (e.g. 'anthropic/claude-sonnet-4.6'), Gateway is already default in AI SDK L700: needed. Always curl https://ai-gateway.vercel.sh/v1/models first; never trust model IDs from memory L701: - For durable agent loops or untrusted code: use Workflow (pause/resume/state) + Sandbox; use Vercel MCP for secure infra access`; ... L790: telemetry2.trackCliFlagHelp("agent"); L791: output_manager_default.print(help(agentCommand, { columns: client.stderr.columns })); L792: return 2;
    Critical
    Trigger Reachable Dangerous Capability

    A package entrypoint or install-time lifecycle script reaches a source file with blocking dangerous behavior.

    dist/commands-bulk.jsView on unpkg · L2
    471import { L472: require_execa L473: } from "./chunks/chunk-24FCBXI4.js";
    High
    Shell

    Package source references shell execution.

    dist/commands-bulk.jsView on unpkg · L471
    4357); L4358: const testUrl = `https://${deployment.url}${subpath}`; L4359: output_manager_default.log(`${import_chalk18.default.bold("Deployment URL:")} ${link_default(testUrl)}`); ... L4368: if (run3) { L4369: const proc = await (0, import_execa.default)(run3, [testUrl], { L4370: stdio: "inherit", ... L4372: env: { L4373: ...process.env, L4374: HOST: deployment.url,
    High
    Same File Env Network Execution

    A single source file combines environment access, network access, and code or shell execution; review context before blocking.

    dist/commands-bulk.jsView on unpkg · L4357
    2import { fileURLToPath as __fileURLToPath } from 'node:url'; L3: import { dirname as __dirname_ } from 'node:path'; L4: const require = __createRequire(import.meta.url); ... L471: import { L472: require_execa L473: } from "./chunks/chunk-24FCBXI4.js"; ... L699: - Use AI Gateway for model routing, set AI_GATEWAY_API_KEY, using a model string (e.g. 'anthropic/claude-sonnet-4.6'), Gateway is already default in AI SDK L700: needed. Always curl https://ai-gateway.vercel.sh/v1/models first; never trust model IDs from memory L701: - For durable agent loops or untrusted code: use Workflow (pause/resume/state) + Sandbox; use Vercel MCP for secure infra access`; ... L790: telemetry2.trackCliFlagHelp("agent"); L791: output_manager_default.print(help(agentCommand, { columns: client.stderr.columns })); L792: return 2;
    High
    Sandbox Evasion Gated Capability

    Source gates dangerous network, credential, or execution behavior behind CI, host, platform, time, or geo fingerprint checks.

    dist/commands-bulk.jsView on unpkg · L2
    2import { fileURLToPath as __fileURLToPath } from 'node:url'; L3: import { dirname as __dirname_ } from 'node:path'; L4: const require = __createRequire(import.meta.url); ... L471: import { L472: require_execa L473: } from "./chunks/chunk-24FCBXI4.js"; ... L699: - Use AI Gateway for model routing, set AI_GATEWAY_API_KEY, using a model string (e.g. 'anthropic/claude-sonnet-4.6'), Gateway is already default in AI SDK L700: needed. Always curl https://ai-gateway.vercel.sh/v1/models first; never trust model IDs from memory L701: - For durable agent loops or untrusted code: use Workflow (pause/resume/state) + Sandbox; use Vercel MCP for secure infra access`; ... L790: telemetry2.trackCliFlagHelp("agent"); L791: output_manager_default.print(help(agentCommand, { columns: client.stderr.columns })); L792: return 2;
    Low
    Weak Crypto

    Package source references weak cryptographic algorithms.

    dist/commands-bulk.jsView on unpkg · L2
    dist/get-latest-worker.cjsView file
    16L17: const { mkdirSync, writeFileSync } = require('fs'); L18: const { access, mkdir, readFile, unlink, writeFile } = require('fs/promises');
    Medium
    Dynamic Require

    Package source references dynamic require/import behavior.

    dist/get-latest-worker.cjsView on unpkg · L16
    dist/chunks/chunk-RB7WQKNC.jsView file
    path = dist/chunks/chunk-RB7WQKNC.js kind = oversized_source_file sizeBytes = 2484789 magicHex = [redacted]
    High
    Oversized Source File

    Package contains source files above the static scanner size ceiling.

    dist/chunks/chunk-RB7WQKNC.jsView on unpkg

    Findings

    2 Critical6 High5 Medium8 Low
    CriticalCredential Exfiltrationdist/commands-bulk.js
    CriticalTrigger Reachable Dangerous Capabilitydist/commands-bulk.js
    HighChild Processdist/index.js
    HighShelldist/commands-bulk.js
    HighSame File Env Network Executiondist/commands-bulk.js
    HighSandbox Evasion Gated Capabilitydist/commands-bulk.js
    HighCross File Remote Execution Contextdist/index.js
    HighOversized Source Filedist/chunks/chunk-RB7WQKNC.js
    MediumDynamic Requiredist/get-latest-worker.cjs
    MediumNetwork
    MediumEnvironment Vars
    MediumProtestware
    MediumStructural Risk Force Deep Review
    LowScripts Present
    LowEval
    LowWeak Cryptodist/commands-bulk.js
    LowFilesystem
    LowObfuscated
    LowHigh Entropy Strings
    LowTelemetry
    LowUrl Strings