Back to skill

Security audit

Vercel Speed Audit

Security checks for vulnerabilities and agentic risk

Overview

This Vercel optimization skill is coherent, but its copy-paste CI deployment examples use unpinned tooling with production deployment tokens, which deserves review before installation or use.

Review the CI workflow examples before copying them. Pin the Vercel CLI and GitHub Actions to reviewed versions or commit SHAs, prefer project-local lockfile-controlled tools over global installs, and use narrowly scoped Vercel tokens with protected GitHub environments for production deploys. The skill does not show malicious behavior, but its deployment examples affect production infrastructure and should be hardened first.

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 (3)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:22
Finding
Unpinned packages are executed through npx<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:22-26`, `docs/checklist.md:170-173`, `docs/general.md:274-276` **Vulnerability Type**: Unpinned third-party package execution **Risk Level**: Medium ### Vulnerable Code `SKILL.md:22-26`: ```bash # 1. Check current build times cd <project> && npx vercel ls --limit 5 # 2. Check team/plan tier npx vercel team ls ``` `docs/checklist.md:170-173`: ```bash # Check for duplicates npx depcheck # Find unused dependencies npx npm-check # Interactive update/remove ``` `docs/general.md:274-276`: ```json { "ignoreCommand": "npx turbo-ignore" } ``` ### Technical Analysis The Skill instructs users and automated Vercel builds to invoke packages through `npx` without specifying reviewed versions. If a package is not already installed locally, `npx` can retrieve and execute it from the configured package registry. This introduces a mutable supply-chain boundary: the code executed during a later Skill invocation may differ from the code available when the Skill was audited. The risk is particularly significant for `npx turbo-ignore` because it may execute as part of Vercel's ignored-build decision rather than only during an explicit local audit. No evidence establishes that the named packages are currently malicious. The vulnerability is the unsafe execution pattern and its exposure to future package compromise, registry compromise, or unexpected dependency resolution. ### Attack Path 1. An attacker compromises a referenced package, one of its transitive dependencies, or the package registry resolution path. 2. A user follows the Skill, or Vercel evaluates the configured `ignoreCommand`. 3. `npx` resolves and downloads the unpinned package version. 4. The package's executable or installation lifecycle code runs with the privileges of the local user, CI runner, or Vercel build environment. 5. Malicious code reads accessible source files, environment variables, package-manager credentials, or ...[truncated 659 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add required audit tools and the Vercel CLI as development dependencies using explicitly reviewed versions. 2. Commit the corresponding lockfile and require immutable installation: ```bash pnpm install --frozen-lockfile ``` 3. Invoke locally installed executables rather than allowing network installation: ```bash pnpm exec vercel ls --limit 5 pnpm exec depcheck ``` 4. If `npx` must be retained, specify an exact version and prevent fallback installation where practical: ```bash npx --no-install vercel ls --limit 5 ``` 5. Replace `npx turbo-ignore` in persistent deployment configuration with a project-local, lockfile-controlled command. 6. Review package provenance, lifecycle scripts, maintainers, and transitive dependencies before approving version updates. 7. Run dependency-audit utilities without production secrets and with minimum filesystem and network privileges. ]]>

T08 · Insecure Dependencies

Error
Location
docs/github-actions-prebuilt.md:72
Finding
CI installs the latest Vercel CLI without a locked version<![CDATA[ ## Vulnerability Details **File Location**: `docs/github-actions-prebuilt.md:72-84`, `docs/github-actions-prebuilt.md:110-124`, `docs/github-actions-prebuilt.md:168-182`, `docs/github-actions-prebuilt.md:207-213` **Vulnerability Type**: Unpinned privileged CI dependency **Risk Level**: High ### Vulnerable Code Representative production deployment sequence from `docs/github-actions-prebuilt.md:72-84`: ```yaml - name: Install dependencies run: pnpm install --frozen-lockfile - name: Install Vercel CLI run: pnpm add -g vercel - name: Pull Vercel environment run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }} - name: Build project run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }} - name: Deploy prebuilt output run: | DEPLOY_URL=$(vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}) echo "Deployed to: $DEPLOY_URL" echo "DEPLOY_URL=$DEPLOY_URL" >> $GITHUB_ENV ``` A second installation variant appears at `docs/github-actions-prebuilt.md:207-213`: ```yaml - name: Install Vercel CLI run: npm i -g vercel - name: Download build artifact uses: actions/download-artifact@v4 with: name: vercel-output path: .vercel/output ``` ### Technical Analysis Both `pnpm add -g vercel` and `npm i -g vercel` resolve the current registry release rather than a version approved during review. The globally installed executable is subsequently given a Vercel authentication token and is used to retrieve environment configuration, build the project, and deploy to production. A compromised Vercel CLI release or transitive dependency would therefore execute immediately before credentials are supplied to that same runner. Global installation also places the executable outside the project's lockfile-controlled dependency graph, so `--frozen-lockfile` does not protect it. No malicious behavior by the current Vercel package was identified. The finding concerns the failure to lock a privi ...[truncated 1453 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Declare the Vercel CLI as a project development dependency at an exact reviewed version: ```bash pnpm add --save-dev --save-exact vercel@<reviewed-version> ``` 2. Commit `pnpm-lock.yaml` and install only through: ```bash pnpm install --frozen-lockfile ``` 3. Invoke the lockfile-controlled binary: ```yaml - run: pnpm exec vercel pull --yes --environment=production --token="${{ secrets.VERCEL_TOKEN }}" ``` 4. Remove all global `npm i -g vercel` and `pnpm add -g vercel` steps. 5. Use a dedicated deployment token with the narrowest available team, project, and operation scope. Do not use a broadly privileged personal token. 6. Separate build and deployment responsibilities where practical. The build job should not receive production deployment credentials unless required. 7. Add dependency review and controlled update automation so Vercel CLI upgrades require review and successful security testing. 8. Protect production environments with GitHub Environment approvals and restrict which branches and actors can access production secrets. 9. Avoid exposing tokens in command arguments where supported; prefer a protected environment variable or the CLI's documented secure authentication mechanism. ]]>

T08 · Insecure Dependencies

Warning
Location
docs/github-actions-prebuilt.md:51
Finding
GitHub Actions are referenced through mutable major-version tags<![CDATA[ ## Vulnerability Details **File Location**: `docs/github-actions-prebuilt.md:51-60`, with repeated instances throughout the workflow examples **Vulnerability Type**: Mutable CI action dependencies **Risk Level**: Medium ### Vulnerable Code `docs/github-actions-prebuilt.md:51-60`: ```yaml jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v4 with: node-version: 22 cache: 'pnpm' - run: pnpm install --frozen-lockfile ``` Additional workflow examples use mutable tags including: ```yaml - uses: actions/github-script@v7 - uses: actions/upload-artifact@v4 - uses: actions/download-artifact@v4 - uses: actions/cache@v4 ``` ### Technical Analysis The workflows reference GitHub Actions by mutable major-version tags. A tag such as `v4` or `v7` can move to a different commit after repository review, meaning the code executed by CI is not cryptographically tied to the audited implementation. Third-party Actions run directly on the job runner. A malicious or compromised Action can inspect the workspace, alter files, persist processes for later workflow steps, influence outputs, or capture credentials subsequently made available to the runner. The official `actions/*` components have a comparatively strong trust profile, but immutable commit pinning remains necessary to prevent Action code from changing outside the repository's own review process. `pnpm/action-setup` is also an independently maintained Action and should receive the same control. ### Attack Path 1. An attacker compromises an Action repository, maintainer account, release process, or mutable release tag. 2. The `v4` or `v7` tag is changed to reference attacker-controlled code. 3. A push or pull-request event starts one of the documented workflows. 4. GitHub downloads and executes the changed Action on the runner. 5. The Action reads or modifies the checked-ou ...[truncated 958 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every Action to a reviewed full commit SHA: ```yaml - uses: actions/checkout@<full-commit-sha> # v4.x.y ``` 2. Preserve the human-readable release number in a comment while treating the commit SHA as the security boundary. 3. Configure dependency-update automation to propose reviewed SHA updates rather than following moving major tags automatically. 4. Add explicit minimum workflow permissions. For example: ```yaml permissions: contents: read ``` 5. Grant `pull-requests: write` only to the job that must post a preview comment, rather than to the entire workflow. 6. Put production deployment behind a protected GitHub Environment with required reviewers and restricted branches. 7. Ensure untrusted pull-request code cannot receive deployment secrets, especially for pull requests originating from forks. 8. Isolate build and deployment jobs, verify downloaded artifact checksums or attestations, and deploy only artifacts produced by approved workflow runs. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (9)

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding
The skill instructs users to run `npx vercel` without pinning a specific package version, which causes npm to resolve and execute whatever version is current at runtime. If the upstream package is compromised, a malicious version is published, or a future release changes behavior, users could execute unreviewed code on their workstation or CI environment.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding
This command also uses `npx vercel` without a pinned version, so it may download and run an untrusted or newly changed package version at execution time. In a developer-tooling skill, that is materially risky because the command is likely to be copied directly into a shell by users with access to source code, tokens, and deployment context.

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.

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.

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.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding
The documentation recommends running `npx turbo-ignore` without pinning an explicit package version. `npx` may fetch the latest published package at execution time, which creates a supply-chain risk: a malicious or compromised upstream release could execute arbitrary code in the user's environment or CI when the command is used.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding
This finding repeats the same risky guidance: invoking `npx turbo-ignore` without a pinned version allows resolution of whatever package version is current at runtime. In CI/CD or developer environments, that can lead to unexpected code execution if the package is hijacked, maliciously updated, or otherwise compromised.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
### Option 1: Disable in Vercel Dashboard

Project Settings → Git → uncheck "Auto-deploy" for all branches.

### Option 2: Ignored Build Step (Safer)
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
The example sets `regions: ['iad1']` with an inline comment labeling it as the US East default. This is a natural-language locale recommendation that steers users to a specific region without opt-in or explanation that the guidance is only for US-based workloads.

Static analysis

No suspicious patterns detected.