Launch sale: 20% off Fix Pack, Deep Audit and Monitor through Nov 30, 2026. The scan stays free. See sale prices →
Home / Guides / Cursor-built app security checklist

Cursor-built app security checklist: keys, .cursorignore and what to review

Cursor writes code in your own repo, so you control where secrets live and what gets deployed. That's a strength, but generated code often takes the shortest path to working: a key in the front end, an API route without an auth check, a table without RLS. Use this list before each launch.

Scan your live app free  Passive, no signup, never touches your database.

1. Keep secrets out of the agent's context

Cursor ignores files in .gitignore plus a default list that includes .env*. Add anything else sensitive (credentials.json, *.pem, *.key) to .cursorignore, or to the global ignore list in Cursor's settings. Cursor's docs note that the terminal and MCP tools the agent uses can't be blocked by .cursorignore, and that complete protection isn't guaranteed, so don't paste live keys into chat.

# .cursorignore (gitignore syntax)
**/.env
**/.env.*
**/credentials.json
**/secrets.json
**/*.pem
**/*.key

2. Keep secrets out of git

Make sure .env and .env.* are in .gitignore before the first commit. If a key was ever committed, rotate it; deleting the file doesn't remove it from history.

3. Check what your bundler makes public

NEXT_PUBLIC_ (Next.js) and VITE_ (Vite) variables are inlined into JavaScript that browsers download. Only publishable values belong there: a Supabase URL and publishable/anon key, a Stripe pk_ key. Search your build output for secret prefixes:

# after building locally (Vite: dist/, Next.js: .next/static/)
grep -rEo "sk_(live|test)_[0-9A-Za-z]{10}|sk-proj-[0-9A-Za-z_-]{10}|sb_secret_[0-9A-Za-z_-]{6}|rk_(live|test)_[0-9A-Za-z]{10}|whsec_[0-9A-Za-z]{10}" dist/ .next/static/ 2>/dev/null

4. Review every generated API route and server action

Ask: who can call this, and does it check that the record belongs to the caller? Generated handlers often trust an ID from the request body. Add authentication and ownership checks inside each handler, not just in the UI.

5. Lock down the database

If the browser talks to Supabase or Firebase directly, Row Level Security or Security Rules are your real access control. Use our Supabase RLS SQL or Firebase rules checklist.

6. Add security headers and turn off source maps

Add CSP, HSTS, X-Frame-Options, nosniff and Referrer-Policy at your host, and keep production browser source maps off (Next.js: productionBrowserSourceMaps stays false; Vite: build.sourcemap false).

7. Ask Cursor to review, then verify

A useful prompt: "List every place this codebase reads a secret, every API route and whether it checks auth and ownership, and every NEXT_PUBLIC_/VITE_ variable." Treat the answer as a lead to check, not a guarantee.

8. Scan the deployed app

Run Unspill on your production URL. It checks the files a visitor's browser downloads for leaked keys, exposed .env/.git, public source maps and missing headers.

Fix guides for these issues

FAQ

Does Cursor read my .env file?

Per Cursor's docs, .env* files are on its default ignore list, along with anything in .gitignore and .cursorignore, so Agent, Tab and @-mentions can't access them. The docs also say the agent's terminal and MCP tools aren't blocked by .cursorignore and that protection isn't guaranteed.

Is code written by Cursor less secure?

Not inherently, but generated code tends to take the shortest path to working. Review secrets handling, auth checks and database rules before shipping, as you would for any code.

Sources

Last checked against these sources on 2026-10-19. Platforms change; when in doubt, the official docs win.

Want help fixing this?

We're opening a done-for-you fix service, a deep audit (database rules, auth, user-to-user data access) and continuous monitoring. Join the waitlist to get first access. No spam, and we never share your email.