Back to skill

Security audit

Nextjs

Security checks for vulnerabilities and agentic risk

Overview

This is mostly a Next.js documentation skill, but it needs Review because some examples could teach agents to expose session/config data and its install/migration commands run mutable remote packages.

Review before installing. Prefer pinned installer and codemod versions, avoid copying the example that returns cookie tokens or server-only environment values to clients, and add privacy/consent checks before using analytics, tag-manager, maps, or embedded third-party scripts.

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

Warning
Location
references/route-handlers.md:81
Finding
Authentication Cookie Token Disclosed in JSON Response<![CDATA[ ## Vulnerability Details **File Location**: `references/route-handlers.md:81-84` **Vulnerability Type**: Authentication credential disclosure **Risk Level**: Medium ### Vulnerable Code ```tsx const cookieStore = await cookies() const token = cookieStore.get('token') return Response.json({ query, token }) ``` ### Technical Analysis The example reads an authentication token from the server-side cookie store and serializes the cookie object into a JSON response. If the cookie is marked `HttpOnly`, returning its value through an API response defeats that protection by making the credential available to client-side JavaScript and other response consumers. The response may also be captured by browser extensions, application telemetry, reverse-proxy logs, debugging tools, monitoring systems, or improperly configured caches. Applications that adopt this example with real session credentials could therefore disclose reusable authentication material. Although this is documentation rather than an automatically executed handler, it presents an insecure implementation pattern that developers may copy into production applications. ### Attack Path 1. A developer implements the documented request-helper example using a real authentication cookie. 2. An authenticated user requests the affected route handler. 3. The server reads the user's token from the cookie store. 4. The handler includes the token in its JSON response. 5. Malicious client-side code, a compromised browser extension, logging infrastructure, or another party able to observe the response obtains the token. 6. If the token is reusable, the attacker submits it to authenticated endpoints and impersonates the victim. ### Impact Assessment An attacker who obtains a reusable session token may gain the same application privileges as the affected user. Depending on the victim account, this could allow access to private data, modification of account resources, or administrative operations. The scop ...[truncated 217 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never include authentication tokens, session identifiers, authorization headers, or complete cookie objects in API responses. - Use the token exclusively on the server to authenticate the request. - Return only the minimum non-sensitive information required by the client, such as an authenticated Boolean or a sanitized user profile. - Explicitly document that `HttpOnly` credentials must not be copied into client-readable responses. - Add authorization checks before returning protected data. - Apply restrictive cache controls to authenticated responses, for example: ```tsx export async function GET(request: Request) { const cookieStore = await cookies() const token = cookieStore.get('token')?.value const user = token ? await validateSession(token) : null if (!user) { return Response.json( { error: 'Unauthorized' }, { status: 401, headers: { 'Cache-Control': 'no-store' }, }, ) } return Response.json( { query: new URL(request.url).searchParams.get('q'), user: { id: user.id, name: user.name, }, }, { headers: { 'Cache-Control': 'private, no-store' }, }, ) } ``` ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:35
Finding
Unpinned Third-Party Packages Executed Through npx<![CDATA[ ## Vulnerability Details **File Locations**: - `README.md:35` - `README.md:41` - `SKILL.md:19` - `references/async-patterns.md:86` - `references/file-conventions.md:149` - `references/self-hosting.md:314` - `references/self-hosting.md:316` **Vulnerability Type**: Unpinned dependency execution and mutable upstream installation sources **Risk Level**: Medium ### Vulnerable Code `README.md:35`: ```bash npx add https://github.com/wpank/ai/tree/main/skills/frontend/nextjs ``` `README.md:41` and `SKILL.md:19`: ```bash npx clawhub@latest install nextjs ``` `references/async-patterns.md:86`: ```bash npx @next/codemod@latest next-async-request-api . ``` `references/file-conventions.md:149`: ```bash npx @next/codemod@latest upgrade ``` `references/self-hosting.md:314-316`: ```bash npx create-sst@latest # or npx @opennextjs/aws build ``` ### Technical Analysis The documented commands use `npx` to download and immediately execute packages without pinning them to reviewed versions. The explicit `@latest` references guarantee that the executed implementation may change over time. The GitHub installation command also targets a mutable repository path rather than an immutable commit. `npx` execution may run package entry points and installation lifecycle scripts with the permissions of the invoking user. Consequently, compromise of an upstream package, maintainer account, package registry, or referenced repository could turn an otherwise legitimate command into arbitrary local code execution. This does not establish that any currently referenced package is malicious. The risk arises because the effective code executed by future users is not fixed to the content that was reviewed during this audit. ### Attack Path 1. An attacker compromises an upstream package, publisher account, registry release process, or mutable GitHub repository. 2. The attacker publishes a malicious version under the package name referenced by the documentation or modifies the ...[truncated 1194 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace `@latest` with exact, reviewed package versions. - Pin GitHub-sourced content to an immutable commit SHA rather than a branch or mutable repository path. - Verify package provenance, publisher identity, release signatures, and checksums before execution. - Prefer adding reviewed tools to project development dependencies and executing the lockfile-resolved local binary. - Use lockfiles with integrity metadata and enforce immutable or frozen installations in CI/CD. - Review package lifecycle scripts before allowing them to run. - Execute migration and installation tools in an isolated environment with minimal credentials and filesystem access. - Document the expected package name, version, checksum, and trusted source. For example: ```bash npm install --save-dev --save-exact @next/codemod=<reviewed-version> npx --no-install next-codemod next-async-request-api . ``` For repository installation, use an immutable reviewed revision: ```bash # Replace the placeholder with a reviewed full commit SHA. npx add https://github.com/wpank/ai/tree/<reviewed-full-commit-sha>/skills/frontend/nextjs ``` ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Rogue AgentSelf-Modification, Session Persistence
Findings (21)

Unvalidated Output Injection

High
Category
Output Handling
Content
```tsx
// BAD: Missing id
<Script dangerouslySetInnerHTML={{ __html: 'console.log("hi")' }} />

// GOOD: Has id
<Script id="my-script" dangerouslySetInnerHTML={{ __html: 'console.log("hi")' }} />
Confidence
65% confidence
Finding
Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.

Unvalidated Output Injection

High
Category
Output Handling
Content
```tsx
// BAD: Missing id
<Script dangerouslySetInnerHTML={{ __html: 'console.log("hi")' }} />

// GOOD: Has id
<Script id="my-script" dangerouslySetInnerHTML={{ __html: 'console.log("hi")' }} />
Confidence
65% confidence
Finding
Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding
The README instructs users to execute remote package/code via `npx add` from a GitHub URL without pinning to a specific immutable version, tag, or commit. This creates a supply-chain risk because future upstream changes or compromise of the referenced source could cause different code to run than what was originally reviewed.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding
Using `npx clawhub@latest install nextjs` pulls and executes the latest version of a remote package at runtime, which is inherently mutable. If the package is updated maliciously or compromised, users following the README may execute attacker-controlled code.

Session Persistence

Medium
Category
Rogue Agent
Content
From your project root:

```bash
mkdir -p .cursor/skills
cp -r ~/.ai-skills/skills/frontend/nextjs .cursor/skills/nextjs
```
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Skill Enumeration

Medium
Category
Agent Snooping
Content
From your project root:

```bash
mkdir -p .claude/skills
cp -r ~/.ai-skills/skills/frontend/nextjs .claude/skills/nextjs
```
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Skill Enumeration

Medium
Category
Agent Snooping
Content
#### Claude Code (global)

```bash
mkdir -p ~/.claude/skills
cp -r ~/.ai-skills/skills/frontend/nextjs ~/.claude/skills/nextjs
```
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

External Model or Provider Selection

Medium
Category
Excessive Agency
Content
---
name: nextjs
model: standard
description: Next.js App Router best practices — Server Components, data fetching, caching, routing, middleware, metadata, error handling, streaming, Server Actions, and performance optimization for Next.js 14-16+.
keywords: [next.js, nextjs, app router, server components, rsc, server actions, streaming, suspense, parallel routes, intercepting routes, metadata, middleware, caching, revalidation, image optimization, font optimization]
user-invocable: false
Confidence
90% confidence
Finding
Skill selects an external model or provider that may use a different account or billing plan than the operator expects. Undisclosed model switches can cause unexpected cost or quota consumption.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
The installation command uses `npx clawhub@latest install nextjs`, which executes a remote package at its latest published version rather than a pinned, reviewed release. This creates a supply-chain risk: a compromised or malicious upstream release could execute arbitrary code on the user's machine at install time.

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.

External Transmission

Medium
Category
Data Exfiltration
Content
const users = await db.user.findMany();

  // Or fetch from external API
  const posts = await fetch('https://api.example.com/posts').then(r => r.json());

  return (
    <ul>
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
The documentation instructs users to run `npx @next/codemod@latest upgrade`, which fetches and executes remote package code without pinning to a specific reviewed version. If the upstream package is compromised, malicious, or changed unexpectedly, users could execute attacker-controlled code during the migration step. In a developer skill focused on framework best practices, this is more dangerous because readers are likely to copy-paste the command directly into a trusted shell environment.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The example reads a token from cookies and returns it in a JSON response, which normalizes exposing credential material back to the client. In a documentation skill about Next.js route handlers, readers may copy this pattern into real APIs, causing session tokens or auth secrets to be disclosed to browsers, logs, intermediaries, or attacker-controlled scripts.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This markdown file recommends integrating Google Analytics, Google Tag Manager, YouTube embeds, Google Maps embeds, and other third-party scripts, all of which can transmit user or system data to external services. The documentation does not include any warning about privacy impact, consent requirements, or the fact that these integrations may collect user data.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The runtime config example returns values derived from server-side environment variables directly from an API route without warning that only explicitly safe, non-secret values should be exposed. Readers may copy this pattern and accidentally leak internal URLs, feature flags, deployment metadata, or even sensitive configuration if they broaden the response later.

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.

Natural-Language Policy Violations

Low
Confidence
80% confidence
Finding
This is a natural-language policy concern because the document uses absolute language to force particular choices regardless of user preference or project context. The rule set allows documented, justified constraints, but these lines present blanket requirements rather than optional recommendations or scoped guidance.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
This markdown file applies to SQP-3, and the embedded example sets the HTML language to English explicitly. Because the file does not indicate that English is optional or justified by a region-specific requirement, it may conflict with language/locale policy expectations.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
This example repeats the same locale constraint by setting the document language to English. Repeated guidance can normalize a fixed-language default without clarifying that the locale should be chosen based on user or application context.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
This is another natural-language policy issue in an example string literal affecting locale handling. The example provides no indication that developers should adapt the value to their users' locale, which can encourage unnecessary English-only defaults.

Static analysis

No suspicious patterns detected.