Security for apps built with Cursor
Cursor is an editor, not a platform, so a Cursor-built app can be anything: a Vite SPA on Netlify, a Next.js app on Vercel, a Python API on a VPS. That makes the security picture depend on your stack, but a few problems follow AI-written code everywhere. This page covers them.
What changes when an agent writes the code
With Cursor you see every diff, which is an advantage over hosted builders. In practice, though, long agent sessions produce changes faster than anyone reviews them. The agent optimises for making the error go away. If a key is missing in the browser, it will happily expose the key to the browser. If a database query is denied, it may relax the rule that denied it.
Cursor itself leaves few traces in a deployed app. We detect it only when the source references a .cursor/ directory or cursor.sh. That is fine: none of the checks depend on knowing the tool, and the fix prompts work in Cursor whatever we detect.
Problems that follow AI-written code
- Client env prefixes:
VITE_,NEXT_PUBLIC_,REACT_APP_andEXPO_PUBLIC_all mean “put this in the public bundle”. A secret with one of these names is leaked. - Source maps in production, which publish your original source.
- Supabase or Firebase used from the client with rules that allow anonymous reads.
- No Content-Security-Policy, so a single injected script can do anything on the page.
- Committed
.envfiles that end up on the server and become downloadable.
What Shypset checks
You paste the URL; we never see your repository. Public checks read the page and the scripts it loads like a browser: about 40 secret patterns, service_role keys, source maps, Supabase and Firebase configuration in client code, response headers, TLS, DNS and email. Verified checks, after domain verification, probe referenced Supabase tables and an exposed Firebase Realtime Database for anonymous reads, and look for files like /.env and /.git/config.
Shypset is a passive external check. It does not log in to your app and does not test application logic such as SQL injection or IDOR, so a clean report means nothing is visible from outside, not that the app is secure.
Fixing it with Cursor
Every finding comes with a prompt you can paste into Cursor’s agent. Good prompts name the file, the exact problem and what “done” means, and that is how ours are written. Review the diff before accepting, rotate any key that was exposed, deploy, then rescan to see the finding disappear in the diff between scans.
Example finding
A Public finding from a Cursor-built Vite app, with the prompt for Cursor.
Evidence
Exposed maps: https://app.example.com/assets/index-a1b2c3.js.map, https://app.example.com/assets/vendor-d4e5f6.js.map, https://app.example.com/assets/admin-0a9b8c.js.map Secrets found inside the maps: yes
Fix prompt
Production serves JavaScript source maps from /assets/*.js.map. In vite.config.ts set build.sourcemap to false for production builds (or "hidden" if we upload maps to an error tracker), and make sure no .map file is deployed. Then search src/ for any secret that was visible in those maps and tell me which ones I need to rotate.
Questions
- Can Shypset scan my Cursor project before I deploy?
- Not yet. It checks a running site by URL. Deploy to a preview or staging URL and scan that.
- Do the fix prompts work in Cursor?
- Yes. They are plain instructions tied to the finding, written to be pasted into an AI coding agent.
Scan your Cursor-built app
Paste your deployed URL on the home page. Any stack, any host.
Scan your app