Is my Windsurf app secure?
Windsurf writes code in the repo you have open. The security question is about the app you then deploy, not about the editor window. Agents are helpful, and they will happily weaken a rule if that makes the error go away.
Free check
Check the live app
Paste the public Windsurf URL. The check reads what a visitor's browser can already see, then gives you a private report with a fix prompt for each issue.
What Windsurf actually ships
Windsurf is an AI code editor. Cognition now ships that same editor as Devin Desktop. It does not host your app and it does not choose React, Next.js, Python, or anything else. Whatever stack the agent built is the stack you have. The mistakes below are the ones that show up across those stacks when an agent is rushing a feature out.
Mistakes worth checking
These are the ones that show up in apps built with Windsurf. Each step is something you can do in the browser or in the product dashboard.
Critical
A secret pasted in so the preview will load
When a request fails, the agent may drop a service role key, a database URL, or an API key into the file that is currently open. If that file is a client component, the next deploy publishes the key.
Check it yourself
Search the deployed JavaScript for service_role, postgres://, mongodb://, sk-, sk_live, and rk_. Then search the repo for the same strings outside server-only files.
Critical
A public env prefix copied from a sample
Samples use NEXT_PUBLIC_ or VITE_ so the browser can read a value. The agent copies the prefix onto the next variable, including ones that were supposed to stay on the server.
Check it yourself
Read the env example and the host's environment screen side by side. Secret names should not start with NEXT_PUBLIC_ or VITE_. Confirm by searching the live bundle.
High
A database rule loosened to clear a permission error
Supabase row-level security gets disabled, a policy is set to true, or Firebase rules stay in test mode. The happy path starts working in the agent's preview. Private rows are then readable without a login.
Check it yourself
Open the database dashboard. For Supabase, row-level security should be on for every public table, with policies that match the signed-in user. For Firebase, rules should not set read to true, and Firestore should require request.auth.
Critical
Dotfiles included in the deploy
.env, .git, and .npmrc are local tools. A static export, or a host that serves the repo root, will publish them. Git history can still contain a key you deleted in a later commit.
Check it yourself
Request /.env, /.env.local, /.git/HEAD, /.git/config, and /.npmrc on the live site. Each should be missing. If Git is readable, rotate secrets that ever lived in the repository.
Medium
Source maps left on after a debugging session
An agent that is chasing a production bug may turn source maps on and leave them on. The map can include original source, not just function names.
Check it yourself
Open a production script and look for sourceMappingURL. If the map includes your original files, turn it off in the build (productionBrowserSourceMaps false on Next.js, build.sourcemap false on Vite) and delete the old map.
A prompt you can paste
Paste this into Windsurf, publish again, and run the check a second time. If a key was already on the live site, rotate it in the vendor dashboard. The prompt cannot do that part.
Review the deployed app in this repo for anything a stranger can already see. Fix the code. Do not weaken a rule to make a screen work. 1. Remove secrets from client code and from NEXT_PUBLIC_ or VITE_ variables: service role keys, API keys starting with sk- or sk_live or rk_, webhook secrets, private keys, and database URLs with passwords. The Supabase anon key and a Stripe publishable key may stay in the browser. 2. Read secrets only from server environment variables. Put provider calls in server code. 3. If the app uses Supabase, enable row-level security on every public table and delete policies that allow everyone. If it uses Firebase, replace test-mode rules so reads and writes require a signed-in user. 4. Make sure the host does not serve .env, .git, or .npmrc. Turn off production source maps. 5. List exposed key names for me to rotate. Do not print secret values. Tell me which files you changed.
What the check looks at
- The public page and the JavaScript it loads, for common leaked secret keys: a Supabase service role key, OpenAI, Anthropic, Stripe secret keys, AWS, GitHub, Slack, private keys, and database URLs that include a password. A Supabase anon key is called out as expected in the browser.
- A short list of public paths: /.env, /.env.local, /.env.production, /.git/config, /.git/HEAD, and /.npmrc.
- A source map, only when a script on the page already points at one, and only when that map includes original source.
- Supabase tables, only when the page already includes a supabase.co address and the public anon key. It asks for one row per table, then drops that row.
- Firebase Realtime Database and Firestore, only when the public config is already in the page. It uses that public config and does not sign in.
- A few browser safety headers on the main response. Missing headers are noted when two or more of the watched ones are absent. They are less urgent than a leaked key.
What stays outside it
- It reads. It does not log in, submit forms, or change data.
- It does not guess passwords, fuzz inputs, or hunt through hidden paths.
- It does not use any secret it finds, including a service role key.
- It does not open your builder's dashboard. A rule that lives only there can stay invisible.
- A clear result describes this public look. It is not a certificate that the whole app is safe.
- The check looks at the deployed URL. It does not read the Windsurf or Devin Desktop session, the local repo, or an agent transcript.
Questions
Free check
Run it on the published URL
Use the address a customer would type. The report stays private, and the shareable scorecard hides the details.
Other builders
- Is my Lovable app secure?Service role keys, row-level security, and variables that ship to the browser.
- Is my Bolt app secure?Vite variables, Supabase locks, and Bolt Database access you confirm by hand.
- Is my Replit app secure?Secrets in the page, a public Repl, and DATABASE_URL where a visitor can read it.
- Is my Cursor app secure?Client env prefixes, row-level security, Firebase test mode, and source maps.
- Is my v0 app secure?Next.js client bundles, Vercel env vars, and optional Supabase or Neon.
- Is my Base44 app secure?Entity rules you check by hand, plus Vite secrets and service-role calls.
- Is my Bubble app secure?Privacy rules, API Connector secrets, and the Data API admin token.