Back to skill

Security audit

Nodejs Patterns

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent Node.js backend pattern skill, but its README includes an unsafe unpinned install command and some production security examples need review.

Review the README install command before using it; prefer a pinned ClawHub package, signed release, or immutable commit instead of running the unpinned `npx add` command. If you use the backend snippets, tighten CORS allowlists, sanitize production error responses, and replace loose `any` types before deploying.

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

T08 · Insecure Dependencies

Error
Location
README.md:30
Finding

Unpinned Third-Party Installation Command Creates a Supply-Chain Risk

Content
View full analysis

Vulnerability Details

File Location: README.md:30
Vulnerability Type: Unpinned third-party package and mutable remote source
Risk Level: High

bash
npx add https://github.com/wpank/ai/tree/main/skills/backend/nodejs-patterns

Technical Analysis

The installation instruction invokes an npm executable named add through npx without pinning it to a reviewed version. It also references content under the mutable main branch of an external GitHub repository rather than an immutable commit.

Consequently, the command is not reproducible: the npm package resolved as add, the repository, or the repository branch can change after this Skill has been audited. If either source is compromised or transferred to a malicious maintainer, users following the documented command could execute or install attacker-controlled content with the permissions of the invoking user.

Attack Path

  1. An attacker compromises or takes control of the npm package resolved by npx add, the referenced GitHub account, or the repository.
  2. The attacker publishes a malicious package version or modifies content on the mutable main branch.
  3. A user follows the installation command from the README.
  4. npx retrieves the current unpinned package, and the installation process accesses mutable remote content.
  5. Malicious code or Skill instructions execute or are installed under the invoking user's account.

Impact Assessment

A compromised npm executable could run arbitrary code with the current user's privileges, potentially reading or modifying user-accessible files, credentials, source repositories, and development configuration. Compromised Skill content could also introduce malicious instructions into projects where the Skill is installed. The scope is limited by the privileges and filesystem access of the user running the command.

Remediation
View remediation

Remediation Suggestions

  • Replace the ambiguous npx add invocation with a trusted, fully qualified package name.
  • Pin the installer package to an exact reviewed version.
  • Pin GitHub content to an immutable reviewed commit SHA rather than main.
  • Publish and verify integrity hashes or signed release artifacts.
  • Document the expected files and checksums so users can validate downloaded content before installation.
  • Avoid installation commands that execute newly downloaded package code unless the source and version have been explicitly reviewed.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:63
Finding

Express CORS Configuration Can Fail Open When the Allowlist Is Missing

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:63
Vulnerability Type: Permissive cross-origin resource sharing configuration
Risk Level: Medium

typescript
app.use(cors({ origin: process.env.ALLOWED_ORIGINS?.split(",") }));

Technical Analysis

The recommended Express configuration derives its origin policy from an optional environment variable. If ALLOWED_ORIGINS is absent, the expression evaluates to undefined. The CORS middleware can then apply its permissive default behavior rather than rejecting startup or denying unrecognized origins.

This fail-open behavior is inappropriate for a pattern described as production-ready. The example also does not normalize or explicitly validate configured origins, making deployment mistakes more likely.

Attack Path

  1. A developer copies the documented Express setup.
  2. The application is deployed without ALLOWED_ORIGINS, or the variable is incorrectly configured.
  3. The CORS middleware permits origins that were not explicitly approved.
  4. An attacker hosts a malicious webpage that sends cross-origin requests to the API.
  5. The browser allows the malicious origin to access affected API responses or operations, subject to the API's authentication and credential configuration.

Impact Assessment

The configuration can expose API responses and actions to unintended web origins. If the application later enables credentialed CORS, uses browser-accessible bearer tokens, or exposes unauthenticated sensitive endpoints, an attacker-controlled website may read protected data or trigger application actions. The exact scope depends on the API routes, authentication model, and whether credentials are permitted.

Remediation
View remediation

Remediation Suggestions

  • Require a nonempty origin allowlist in production and terminate startup if it is missing.
  • Validate each request origin against normalized, exact scheme-and-host entries.
  • Reject unknown origins explicitly rather than relying on middleware defaults.
  • Do not use wildcard or reflected origins together with credentialed requests.
  • Add automated tests covering missing, malformed, approved, and rejected origins.
  • Consider a callback-based policy:
typescript
const allowedOrigins = new Set(
  (process.env.ALLOWED_ORIGINS ?? "")
    .split(",")
    .map((origin) => origin.trim())
    .filter(Boolean),
);

if (process.env.NODE_ENV === "production" && allowedOrigins.size === 0) {
  throw new Error("ALLOWED_ORIGINS must be configured in production");
}

app.use(cors({
  origin(origin, callback) {
    if (!origin || allowedOrigins.has(origin)) return callback(null, true);
    return callback(new Error("Origin not allowed"));
  },
}));

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:81
Finding

Fastify CORS Configuration Reflects Arbitrary Request Origins

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:81
Vulnerability Type: Arbitrary-origin CORS policy
Risk Level: Medium

typescript
await fastify.register(cors, { origin: true });

Technical Analysis

Configuring the Fastify CORS plugin with origin: true reflects the request's origin, effectively accepting arbitrary origins. This gives any website an origin that the API treats as permitted and is unsafe as general production guidance.

Although CORS alone does not bypass server-side authentication, reflecting arbitrary origins weakens the browser's same-origin protections. The risk becomes substantially greater if credentials are enabled, authentication tokens are exposed to browser scripts, or sensitive routes are accessible without robust authorization.

Attack Path

  1. A developer copies the documented Fastify configuration into a deployed API.
  2. An attacker creates a website under an attacker-controlled origin.
  3. A victim visits the malicious website.
  4. The website sends cross-origin requests to the API.
  5. Fastify reflects the attacker's origin in its CORS response.
  6. The victim's browser allows the malicious page to read responses or interact with exposed API functionality, subject to the API's authentication controls.

Impact Assessment

Any web origin may be accepted by the API's CORS layer. Depending on surrounding authentication and endpoint behavior, this may permit unauthorized browser-based reading of API data or interaction with sensitive functionality. The issue affects every route covered by the global CORS plugin configuration.

Remediation
View remediation

Remediation Suggestions

  • Replace origin: true with an explicit production allowlist.
  • Reject origins not present in the allowlist.
  • Require production configuration to fail closed when no origins are configured.
  • Keep credential support disabled unless it is strictly required.
  • If credentials are required, permit only exact trusted origins and test the policy against attacker-controlled origins.
  • Use environment-specific configuration with restrictive production defaults.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding

The README instructs users to run npx add against a GitHub URL without pinning to an immutable version, tag, or commit. That creates a supply-chain risk because future changes to the referenced repository could alter what users install, allowing unexpected or malicious content to be fetched at install time.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · README.md (reported line 40)May include surrounding context.

From your project root:

bash
mkdir -p .cursor/skills
cp -r ~/.ai-skills/skills/backend/nodejs-patterns .cursor/skills/nodejs-patterns

Skill Enumeration

Medium
Category
Agent Snooping
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.

Content

Scanner excerpt · README.md (reported line 56)May include surrounding context.

From your project root:

bash
mkdir -p .claude/skills
cp -r ~/.ai-skills/skills/backend/nodejs-patterns .claude/skills/nodejs-patterns

Skill Enumeration

Medium
Category
Agent Snooping
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.

Content

Scanner excerpt · README.md (reported line 63)May include surrounding context.

Claude Code (global)

bash
mkdir -p ~/.claude/skills
cp -r ~/.ai-skills/skills/backend/nodejs-patterns ~/.claude/skills/nodejs-patterns

External Model or Provider Selection

Medium
Category
Excessive Agency
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.

Content

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

md
---
model: standard
description: |
  WHAT: Production-ready Node.js backend patterns - Express/Fastify setup, layered architecture, 
  middleware, error handling, validation, database integration, authentication, and caching.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly says not to expose error details in production, but the global error handler still returns AppError.message to clients for all operational errors. If downstream code puts sensitive details into those messages, attackers can learn internal validation rules, resource existence, authorization logic, or backend behavior, which increases reconnaissance value and may aid exploitation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

L023 explicitly states 'NEVER use any type'. The code contradicts that guidance by using 'public errors?: any[]' in ValidationError at L123, 'Promise' in asyncHandler at L163, and 'value: any' in CacheService.set at L375.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.