Back to skill

Security audit

Sr Next Clerk Expert

Security checks for vulnerabilities and agentic risk

Overview

This Clerk/Next.js skill is mostly coherent, but it includes unsafe authentication and billing examples that could lead developers to ship broken route protection or unapproved Stripe checkout behavior.

Review this skill before installing or using it as an authority source. Do not copy the proxy.ts route matcher as written; protect actual URL paths or use a default-deny pattern with tests. For Stripe, map internal plan IDs to approved server-side Price IDs instead of trusting client input. Treat webhook and billing examples as starting points that require privacy disclosure, retention decisions, signature verification, and idempotent processing.

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)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:60
Finding

Ineffective Clerk Route Protection Due to Filesystem Route-Group Matcher

Content
View full analysis
{ if (isPrivateRoute(request)) { await auth.protect(); } }); ``` ### Technical Analysis The matcher attempts to protect `/(private)(.*)`. However, `(private)` is a Next.js filesystem route group, not a segment included in the public URL. For example, `app/(private)/dashboard/page.tsx` is served at `/dashboard`, not `/(private)/dashboard`. Consequently, requests to `/dashboard`, `/settings`, and other pages stored under the route group do not satisfy this matcher. The middleware therefore skips `auth.protect()`. The separate protected-layout example can mitigate this issue for pages only when developers implement it exactly. It does not make the documented proxy matcher effective, and it does not independently protect API handlers. ### Attack Path 1. A developer copies the documented proxy configuration and places sensitive pages under `app/(private)/`. 2. The developer assumes the proxy protects every route in that filesystem group. 3. An unauthenticated attacker sends a direct request to an actual public path such as `/dashboard`. 4. The matcher tests the request path against `/(private)(.*)`. 5. Because the request URL does not contain the route-group name, the matcher returns false. 6. `auth.protect()` is not called. 7. If the requested page or API lacks a separate server-side authorization check, the attacker accesses the protected functionality or data. ### Impact Assessment The flaw can permit unauthenticated access to routes that developers believe are protected. The exact scope depends on whether individual pages and API handlers perform independent authorization checks. Potential consequences include: - Unauthorized a ...[truncated 405 chars]
Remediation
View remediation
{ if (isPrivateRoute(request)) { await auth.protect(); } }); ``` For stronger default-deny behavior: 1. Define a narrow allowlist of genuinely public routes. 2. Protect every route not included in that allowlist. 3. Explicitly account for sign-in, sign-up, static assets, and public webhook endpoints. 4. Require authentication and authorization inside every sensitive API handler; do not rely exclusively on middleware. 5. Validate ownership or tenant membership for each accessed object. 6. Add integration tests that request every protected URL as an anonymous user and verify a redirect or `401/403` response. 7. Test actual paths such as `/dashboard`, not filesystem paths containing `(private)`. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
references/stripe.md:72
Finding

Client-Controlled Stripe Price ID Allows Selection of Unapproved Billing Prices

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:213
Finding

Unpinned Remote Package Execution Through npx

Content
View full analysis
Remediation
View remediation
middleware-to-proxy ``` Prefer installing the reviewed version through the project's package manager and lockfile before running it: ```bash npm install --save-dev --save-exact @next/codemod@ npx --no-install @next/codemod middleware-to-proxy ``` Additional controls should include: 1. Review the package version and its dependency changes before execution. 2. Commit and enforce the package-manager lockfile. 3. Verify registry provenance and integrity metadata where supported. 4. Use `npx --no-install` after installing the approved dependency locally. 5. Avoid running package tooling with administrator or root privileges. 6. Run codemods in a clean branch or isolated development environment. 7. Review the generated diff before committing or deploying it. 8. Prefer the non-executable manual rename option when the codemod is unnecessary. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (6)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

Environment Variables

bash
# .env.local - COPY FROM CLERK DASHBOARD (do not type manually)
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...

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.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file includes example code that sends the user's email, name, and Clerk identifier to Stripe when a user is created. The document does not include any warning or disclosure that user data will be shared with a third-party billing provider, which is relevant to user privacy and fits the markdown-file warning criterion.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file includes example handlers that extract email, name, and image URL from webhook payloads and create, update, or delete corresponding user records, but it does not provide any user-facing warning about privacy or data-handling implications. Under the markdown criteria for missing warnings, descriptions that affect user data should disclose those behaviors.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The markdown includes <html lang="en"> as the prescribed root layout pattern, which implicitly forces an English locale. Under the policy, locale-specific behavior should either be optional, user-selectable, or explicitly justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The root layout sets lang="en", which enforces an English locale in the example without any visible opt-in, language selection, or justification for a region-specific constraint. Under the policy rule for natural-language locale violations, this is a user-facing language default that should either be configurable or explicitly documented.

Content

No source excerpt is available for this finding.