Checklist

Security Review Checklist — For Your AI Assistant

Hand this document to the AI assistant that already has your codebase — Claude, Cursor, GitHub Copilot, ChatGPT, or similar. It will review your project against every security point below and hand you back a pass/fail report with specific fixes. You don’t have to work through it yourself.

44 checks across 11 areas

How to use it

  1. Open your project in your AI assistant (Claude, Cursor, GitHub Copilot, ChatGPT, etc.).
  2. Copy the document below and paste it in.
  3. The AI reviews your actual code and returns a pass/fail table with a specific fix for each issue.
  4. Confirm, then have it apply the fixes one at a time.

What your AI is told to do

You are an application security reviewer. You have full access to THIS project’s source code (and, where relevant, its deployed site and configuration).

Work through every security check listed below. For each check, inspect the ACTUAL code, configuration, and dependencies — do not assume. Then classify it:
  • PASS — the control is correctly in place. Cite where (file/path).
  • FAIL — the control is missing, disabled, or broken. Cite the file/line and state the concrete risk.
  • NEEDS REVIEW — you cannot confirm it from the code alone (e.g. it depends on server/hosting config or runtime behaviour). Say exactly what a human must check.
  • N/A — the check does not apply to this project. Explain why.

Be strict: if you are not sure a control is correctly implemented, mark NEEDS REVIEW, not PASS.

Present your results as a single Markdown table, grouped by area, with these columns:
  Area | Check | Status | Evidence (file/line or reason) | Fix
List EVERY check. In the Fix column, give a specific, code-level fix for any FAIL (and for NEEDS REVIEW, what to verify).

After the table, add a short “Priority fixes” list of the FAIL items only, worst-first.

Do NOT change any code during this pass — this is an assessment. When I confirm, fix the FAIL items one at a time, showing me each diff before moving on.

The security points it checks

Secrets & keys

The single most common serious finding: credentials shipped where the public can read them.

  • No private keys, API secrets, seed phrases, or database credentials in client-side code, JS bundles, or public reposAnything sent to the browser is effectively public; attackers scrape bundles for keys.
  • Server-side secrets live in environment variables or a secrets manager — never in NEXT_PUBLIC_/VITE_ or other client-exposed configPublic-prefixed variables are embedded directly into the browser build.
  • Any credential that was ever committed or exposed has been rotated — not just deleted from the codeIt remains in git history and may already have been scraped.
  • .env, .git, backups, and config files are not reachable over the webMisconfigured servers often serve these directly to anyone who asks.

Authentication & sessions

Who someone is, proven on the server — not assumed by the UI.

  • Every sensitive action requires a valid, server-verified session — not just a hidden buttonClients can call any endpoint directly, regardless of what the UI shows.
  • Session cookies are HttpOnly, Secure, and SameSiteBlocks theft via cross-site scripting and cross-site request forgery.
  • JWTs are signature-verified on the server and reject “alg: none” and weak keysAn unverified token can be forged to impersonate anyone.
  • No default, shared, or weak admin passwords; multi-factor auth on privileged accountsDefault credentials are the first thing attackers try.
  • Password-reset and email-verification flows can’t be abused to take over accountsA classic and high-impact account-takeover path.

Authorization & access control

Being logged in is not the same as being allowed. Check ownership on every request.

  • The server confirms the logged-in user may access each record — changing an ID in the URL or body must not reveal someone else’s dataInsecure Direct Object Reference (IDOR) is one of the most common real-world API bugs.
  • Role and permission checks happen on the server for every privileged operationUI-only gating is trivially bypassed by calling the API directly.
  • Users can’t escalate privileges by editing requests, roles, or hidden fieldsMass-assignment and privilege-escalation flaws hand out admin access.

APIs & server logic

Your endpoints are the real attack surface — treat every input as hostile.

  • No sensitive endpoint is reachable without authenticationAttackers enumerate hidden and undocumented routes.
  • Inputs are validated and sanitized server-side (type, length, allowed values)Guards against injection (SQL/NoSQL/command) and business-logic abuse.
  • Rate limiting and abuse protection on login, signup, and expensive endpointsStops brute force, credential stuffing, and cost-abuse.
  • Error responses don’t leak stack traces, database queries, or internal hostnamesVerbose errors map out your system for an attacker.
  • CORS is restricted to known origins — never a wildcard combined with credentialsWildcard CORS with credentials can expose logged-in users’ data to any site.

Transport, headers & infrastructure

The plumbing around your app — cheap to get right, dangerous to get wrong.

  • HTTPS everywhere, with a valid, in-date certificate that matches the hostnameWithout TLS, traffic can be read or modified in transit.
  • Security headers set: CSP, HSTS, X-Content-Type-Options, and frame protectionMitigate cross-site scripting, clickjacking, and MIME sniffing.
  • No exposed admin panels, debug endpoints, source maps, or open management portsThese are quick wins attackers scan for continuously.
  • Directory listing is disabled and no sensitive files are servedPrevents casual browsing of your files and data.

Frontend & browser

What runs in your users’ browsers can be turned against them.

  • User-supplied content is escaped/sanitized; avoid injecting untrusted data via innerHTML / dangerouslySetInnerHTMLThe main cause of cross-site scripting (XSS).
  • No sensitive data (tokens, PII) stored in localStorage or sessionStorageAny injected script can read it.
  • A Content-Security-Policy limits which scripts are allowed to runContains the blast radius if an injection does occur.
  • Third-party scripts and embeds are trusted and version-pinnedA compromised widget becomes supply-chain XSS on your site.

Wallets & Web3 (dApps)

In crypto, a single approval can drain a wallet. Slow down before signing.

  • You know exactly what each transaction or signature does before approving — no blind signingMalicious dApps rely on users approving opaque payloads.
  • Token approvals are scoped and limited — avoid unlimited setApprovalForAll or infinite allowancesUnlimited approvals are the classic wallet-drainer mechanism.
  • Contract addresses are verified against an official source before interactingLook-alike or fake contracts exist purely to steal funds.
  • Seed phrases and private keys are never typed into a website or stored digitallyNo legitimate site ever needs them.
  • The dApp domain is the genuine one (watch for look-alike and punycode) and served over HTTPSPhishing clones impersonate real dApps to capture approvals.
  • High-value actions use a hardware wallet and, where possible, transaction simulationAdds a human-verifiable checkpoint before funds move.

Data protection & privacy

You can’t leak what you never stored — and what you do store, protect.

  • Collect only the data you need; encrypt sensitive data in transit and at restMinimizes the impact of any breach.
  • Secrets and personal data are never written to logs or analyticsLogs are widely accessible and frequently leak.
  • Database access is least-privilege — no single all-powerful credential passed aroundLimits how far one compromised credential reaches.

Dependencies & supply chain

Most breaches ride in on code you didn’t write.

  • Lockfiles are committed and dependencies are scanned for known vulnerabilities regularlyThe majority of breaches exploit a known, already-patched CVE.
  • Watch for typosquatted or name-confused packages, especially internal onesDependency-confusion attacks slip malicious packages into builds.
  • Unused dependencies are removed and the rest kept up to dateA smaller dependency surface means fewer vulnerabilities.

Vetting a third-party site (before you send users)

Judging someone else’s site — the exact signals Grid Audit’s Site Safety Check automates.

  • The domain is established (not registered days ago) and matches the real brand — no look-alike or punycode tricksBrand-new and typo domains are the hallmark of phishing.
  • Valid HTTPS certificate and not flagged on threat-intelligence blocklistsBasic, checkable trust signals.
  • No prompts for seed phrases or private keys, unexpected wallet-approval requests, or forced file downloadsDirect theft and malware signals.
  • Re-check right before you rely on it — a site can change or be compromised after any earlier reviewEvery check is point-in-time; “safe yesterday” is not “safe now.”

Ongoing & operational

Security is a practice, not a one-time checkbox.

  • Re-audit after meaningful changes: new endpoints, auth changes, dependency bumps, or infrastructure changesYour security posture changes every time your code does.
  • Monitor for anomalies and keep a written incident-response planFast detection and response limit the damage of an incident.
  • Rotate secrets periodically and whenever someone with access leavesShrinks the window a leaked or stale credential stays useful.

A strong starting point, not a guarantee. An AI self-review isn’t exhaustive and reflects your code at a single moment — re-run it whenever the project changes. It complements, but doesn’t replace, a full Grid Audit against your live application. See the FAQ & Disclaimer for scope and limitations.

Want the real thing?

Grid Audit runs these checks — and many more — against your live application with independent agents, then hands you a prioritized report with fixes. See the audit framework or submit your project.