Works with the AI Agents you already use

    Claude CodeClaude CodeCursorCursorCodex CLICodex CLIMuseMuseDotsDots+22 more

    Secure Code Review for AI-Written Code

    1

    Eight agent skills and two scanners that find and fix the authz, injection, SSRF, XSS, secret-leak and supply-chain bugs AI agents write, mapped to OWASP 2025.

    $29

    Secure checkout via Stripe

    Money-back guarantee

    Converts to your local currency at checkout

    Security scanned
    Secure Code Review for AI-Written Code

    Secure Code Review for AI-Written Code

    Example session with this skill installed

    We're launching our invoicing app next week. Most of it came out of Claude Code. Do a security review of the Next.js app and fix what's critical.

    • Read your context and instructions
    • Compiled the secure code review

    The agent loads secure-code-review, runs the pre-flight, and starts with the scanner:

    $ node scan-code.mjs .
    app\invoices\PayButton.tsx:9  HIGH  public-env-secret  CWE-200  Secret-looking variable behind a public env prefix
        headers: { Authorization: `Bearer ${process.env.NEXT_PUBLIC_STRIPE_SECRET_KEY}` },
        fix: Public prefixes are inlined into the client bundle at build time. Rename without the prefix and read it only in server code.
    app\invoices\actions.ts:6  MEDIUM  server-action-no-auth  CWE-862  Server Action deleteInvoice has no visible authentication or authorization check
        export async function deleteInvoice(id: string) {
        fix: Server Actions are public POST endpoints. Verify the session and the caller's right to this specific record inside the action (or in the data layer it calls), and validate arguments with a schema.
    
    Scanned 9 files: 1 high, 1 medium, 0 low.
    

    It builds for production and checks what actually ships to browsers:

    $ node check-build-secrets.mjs --env .env.production
    .next\static\chunks\442-02vu_mtss.js:1  HIGH  stripe-secret-key  CWE-798  Stripe live secret or restricted key sk_live_De...
    
    Checked 11 files in .next\static: 1 high, 0 other.
    

    Mapping the attack surface turns up what the line scanner cannot see: GET /api/invoices/[id] loads findUnique({ where: { id } }) with no session and no owner check. On a local instance an anonymous request returned another organization's invoice with status 200. The report lists three findings:

    Critical live Stripe secret key in the client bundle (A02/CWE-798; rotate the key now),

    High IDOR on invoices (A01/CWE-639, ASVS 8.2.2),

    High unauthenticated Server Action deleting any invoice (A01/CWE-862, ASVS 8.2.1).

    The fix follows access-control-review: one server-only data access layer that every caller goes through.

    import 'server-only';
    import { cache } from 'react';
    import { cookies } from 'next/headers';
    import { jwtVerify } from 'jose';
    import { db } from '@/lib/db';
    
    const secret = process.env.SESSION_SECRET;
    if (!secret) throw new Error('SESSION_SECRET is not set');
    const key = new TextEncoder().encode(secret);
    
    export const verifySession = cache(async () => {
      const token = (await cookies()).get('__Host-session')?.value;
      if (!token) throw new AuthError(401);
      try {
        const { payload } = await jwtVerify(token, key, { algorithms: ['HS256'], issuer: 'app', audience: 'app' });
        return { userId: String(payload.sub), orgId: String(payload.org), role: payload.role === 'admin' ? 'admin' : 'member' };
      } catch {
        throw new AuthError(401);
      }
    });
    
    export class AuthError extends Error {
      constructor(public status: 401 | 403 | 404) { super(String(status)); }
    }
    
    export async function getInvoice(id: string) {
      const session = await verifySession();
      const row = await db.invoice.findFirst({ where: { id, orgId: session.orgId } });
      if (!row) throw new AuthError(404);
      return { id: row.id, number: row.number, totalCents: row.totalCents, status: row.status };
    }
    
    export async function deleteInvoice(id: string) {
      const session = await verifySession();
      if (session.role !== 'admin') throw new AuthError(403);
      const { count } = await db.invoice.deleteMany({ where: { id, orgId: session.orgId } });
      if (count === 0) throw new AuthError(404);
    }
    

    The Server Action becomes await verifySession(); const id = z.uuid().parse(rawId); await deleteInvoice(id);, the Route Handler maps AuthError to its status, and the Stripe call moves to an authenticated Route Handler that reads STRIPE_SECRET_KEY on the server. After the rebuild:

    $ node scan-code.mjs .
    Scanned 11 files: 0 high, 0 medium, 0 low.
    $ node check-build-secrets.mjs --env .env.production
    Checked 11 files in .next\static: 0 high, 0 other.
    $ curl (no cookie)        /api/invoices/<id>  -> 401
    $ curl (org B session)    /api/invoices/<id>  -> 404
    $ curl (org A session)    /api/invoices/<id>  -> 200 {"id":"...","number":"INV-1","totalCents":1000,"status":"open"}
    $ curl (no cookie) POST   /api/pay            -> 401
    

    All output above is real, from a Next.js 16.4.0 production build with the pack's scripts. The agent then adds the three-case authorization test from verify-fixes.md for each protected operation and puts both scripts in CI.

    Connects securely to your tools. The creator never sees your data.

    About this skill

    AI agents write code that works and ships with the same holes every time: Server Actions anyone can POST to because the page checked auth, invoice lookups by id with no owner condition, update(req.body) that lets a user set their own role, a Stripe secret key behind NEXT_PUBLIC_ because the browser said "undefined", jwt.decode where verify was needed, fetch(userUrl) for link previews, model output in dangerouslySetInnerHTML, || 'dev-secret' fallbacks, and package names that do not exist until an attacker registers them.

    This pack gives your agent a review method and the exact fixes, checked against OWASP Top 10 2025, ASVS 5.0, the OWASP LLM Top 10 2025, CWE 4.20 and current framework docs and advisories:

    • secure-code-review: entry point with pre-flight, attack-surface mapping, severity rubric, and a finding format with evidence, fix and regression test for every issue.
    • access-control-review: IDOR, missing authorization on Server Actions and API routes, a data access layer pattern, tenant isolation, mass assignment, CSRF, CORS, rate limits behind proxies.
    • auth-session-review: JWT verification (jose, jsonwebtoken, PyJWT) that rejects none, key confusion, wrong audience and missing exp; cookies, sessions, password hashing, reset tokens, OAuth callbacks.
    • injection-review: SQL, NoSQL, command, template injection, SSRF with a tested guard, path traversal, open redirects, XSS in React 19 and Next.js, deserialization, uploads.
    • framework-hardening: Next.js 16 (proxy.ts, CSP nonces, image optimizer, every 2025-2026 high and critical advisory with fixed versions), Express 5, Fastify 5, Django 6, FastAPI, Supabase RLS.
    • secrets-exposure: env prefixes per framework, client bundles, logs, and a leak response runbook.
    • supply-chain-review: npm 12 allowScripts, pnpm allowBuilds, release-age gates, hallucinated and typosquatted packages, provenance, trusted publishing.
    • llm-app-security: prompt injection, tool permissions with user-scoped authorization and confirmation, output handling, RAG filters, limits.

    Two zero-dependency Node scripts: scan-code.mjs (45 rules for JS/TS and Python, each finding with file:line, CWE and fix hint) and check-build-secrets.mjs (provider keys, connection strings, .env files, source maps and your own server env values in production build output). Both only read files.

    Every helper in the pack was typechecked and run against bypass inputs; SQL against PostgreSQL 18; Python against Django 6.1 and FastAPI 0.143; Next.js patterns in a real 16.4 build. Defensive scope: it reviews code you own and writes no exploits.

    How to use

    Skills on Agensi run inside your AI agent. Copy the prompt, paste it into your agent, and it connects to Agensi and installs this skill for you. If a payment is needed, your agent shows it to you first.

    Reviews

    No reviews yet

    Be one of the first to try it. Every listed skill passes our trust checks below.

    Security scanned

    Passed our 8-point scan before listing

    Fresh listing

    Recently published to Agensi

    Money-back guarantee

    Doesn't do what its page promises? You get your money back.

    Trust & safety

    Security scanned

    Verified clean 6 days ago

    • Passed all security checks, Safe to install

    Requires

    Python
    @next/codemod
    Node.js

    Listed6 days ago

    What's inside

    Frequently Asked Questions