All posts

Original research

We scanned 120 web apps built with Cursor. Is Cursor-generated code secure?

Cursor is the AI coding tool a lot of developers now write most of their code with. So we scanned 120 real web apps built with it, sourced from GitHub. 12.5% had at least one high-severity security flaw, almost all of them leaked secrets and disabled TLS. That is the same rate we measured for OpenAI Codex and every generation of Claude, because these flaws are not the kind a better tool fixes.

Last updated

Short answer, up front: in our scan, 12.5% of Cursor-built web apps shipped a high-severity security flaw, and that number is statistically the same as the one we measured for Codex and for three Claude model generations. Cursor is not more or less secure than the rest. The security of the app is decided somewhere other than the choice of tool, and this post is about where.

How we found the apps

When Cursor's agent commits code, it writes a co-author trailer into the commit naming Cursor as an author. That trailer is a structural artifact of the tool, not something we keyword-matched, so it lets us attribute a repository's code to Cursor with commit-level precision. We searched GitHub for repositories whose commits are majority-authored by Cursor, which surfaced thousands of candidates, verified each one carried the trailer across most of its history, and sampled the set down to a manageable cohort to scan by hand-reviewable volume.

Then we applied the same web-app filter we use in every study, fixed before we looked at any results: we only scan applications, not libraries, CLIs, or developer tooling, because those have different security profiles and are not what people mean when they ask whether their app is safe. That left 120 Cursor-built web apps, mostly TypeScript and Python, which we scanned with Prbl.

Wondering if your code has any of this? Scan a public repo free, no account needed.

Scan a repo →

The result

12.5% of the Cursor web apps had at least one high-severity security finding. Fifteen of 120. To know whether that is high or low, you need something to compare it against, so here it sits next to every other AI coding tool we have run through the same scanner, same rules, same reviewer.

ToolWeb appsHigh-severity flaw rate
OpenAI Codex829.8%
Cursor (this study)12012.5%
Claude Fable 511613.8%
Claude Opus 4.813016.2%
Claude Opus 4.59617.7%

There is a gentle spread from 9.8% to 17.7%, and it is tempting to read a ranking into it. There is no ranking. With 8 to 21 flagged apps per group, the confidence intervals overlap almost completely, and no pairwise difference between any two tools comes anywhere near statistical significance. Cursor at 12.5% is the same number as Codex at 9.8% and Fable 5 at 13.8%. Five tools, multiple vendors, and one flat line.

What we found in the Cursor apps

Almost everything was a secret that should not have been in the repository, or a transport-security setting that should not have been off. Here is the breakdown by finding class, counted both as affected apps and as total findings.

FindingClassAppsFindings
Hardcoded credentialsCWE-7981031
TLS verification disabledCWE-295411
Weak randomness in a security contextCWE-33033
Timing-unsafe comparisonCWE-20822
Command injectionCWE-7811

The specific patterns, described without identifying any repository:

  • Hardcoded backend keys. The most common finding by a wide margin. A Supabase project URL and its key, or a raw JWT, written directly into committed source. This is the same pattern that dominated our Claude Fable 5 scan and our study of app-builder platforms. Every tool, same leak.
  • TLS verification turned off. A database, mail, or outbound API connection configured to skip certificate checks, which removes the protection against a machine-in-the-middle intercepting the connection.
  • Weak randomness where it counts. Math.random() used to generate a security-sensitive value like a token or an OAuth state parameter. Math.random() is predictable; those values need a cryptographic source.
  • Timing-unsafe comparison. A secret or token compared with a plain === instead of a constant-time check, which can leak the value one character at a time to an attacker measuring response times.

None of these are things a coding tool reasons its way into. They are things a developer pastes in to make something work locally, means to swap for an environment variable later, and commits before later arrives. Cursor writes the surrounding application competently. It does not stop a human from hardcoding a key, because it was never the one deciding to.

Why the tool doesn't move the number

This is the finding that repeats across every study we have published. If the security issues in AI-assisted apps were reasoning failures, subtle logic a tool gets wrong, a better tool would produce fewer of them. It doesn't. The rate is flat from Codex to Cursor to Claude because the flaws that survive review are credential-hygiene mistakes, and credential hygiene is a human workflow problem. No model decides to commit a live key. A person does, to unblock themselves, and the tool faithfully commits what the person wrote.

Why our number is believable

Developer-written web apps are a harder scanning target than template-generated ones, because real developers write migration scripts, dynamic query helpers, and test fixtures whose shape can superficially resemble a vulnerability. Getting an honest number meant making the scanner tell the difference. Before publishing, we reviewed every high-severity finding by hand and traced each false positive back to a specific gap in the scanner, then fixed it and re-scanned all five cohorts through the corrected scanner so the comparison stays fair.

The Cursor rate moved from 14.0% down to 12.5% during that process, as false positives like placeholder keys in test-data files and list-argument subprocess calls were suppressed. The high-severity findings that remain are the ones that do not depend on data flow to be real: a committed key is a committed key regardless of where the value came from.

What to actually do about it

The fix is boring, which is exactly why it gets skipped. Before a Cursor project goes public:

  • Search your own code for supabase.co, apiKey, SECRET, and long random-looking strings. If a key is in a committed file, it is in your git history even after you delete it, so rotate it, don't just remove it.
  • Move every secret to an environment variable and confirm the .env file is in .gitignore before the first push, not after.
  • For anything security-sensitive, use a cryptographic random source, not Math.random().
  • Never ship with certificate verification disabled, and compare secrets with a constant-time function rather than ===.

Frequently asked questions

Is Cursor-generated code secure?

In our scan of 120 real web apps built with Cursor, 12.5% had at least one high-severity security flaw, a rate statistically identical to code from OpenAI Codex and every Claude model we tested. Cursor writes competent code; the flaws that showed up are almost all hardcoded credentials and disabled TLS, which are human paste-ins the tool does not decide on.

What security problems are most common in Cursor code?

Hardcoded credentials were the single most common finding, present in two-thirds of the flagged apps, usually a live API key, JWT, or Supabase key written directly into committed source. Disabled TLS certificate verification was second. Weak randomness for security-sensitive values and timing-unsafe comparisons appeared less often.

Does using a more capable AI coding tool produce more secure code?

No. Across five tools spanning multiple vendors and model generations, the high-severity flaw rate is flat and statistically indistinguishable. The dominant flaws are credential-hygiene mistakes a human introduces to make something work, not reasoning failures a smarter model would avoid.

How do I check my own Cursor project for these issues?

Scan a public repository free with Prbl, no account needed. Or search your own code for strings like supabase.co, apiKey, and SECRET, move every secret to an environment variable, and rotate anything that was ever committed, because it stays in your git history even after you delete it.

Methodology and limits

120 Cursor-built web apps, sourced from GitHub via Cursor's commit co-author trailer, verified across each repository's history, filtered to web applications by a scope rule fixed before any results were seen, and scanned with Prbl. This cohort was scanned alongside 82 Codex, 116 Fable 5, 130 Opus 4.8, and 96 Opus 4.5 web apps under identical rules. Every high-severity finding was manually reviewed, and the false-positive patterns that review surfaced were fixed in the scanner and all cohorts re-scanned before these numbers were computed. See the full cross-tool breakdown in our Codex versus Claude study.

The honest limits: this is observational, not a controlled experiment. The cohorts are different apps by different people, and developers who reach for Cursor skew more technical than the general population, so these rates describe apps built by people who use a coding agent, not all software. Our taint analysis works within a single file, so a value that becomes user-controlled through a call in another file can be under-counted. And no specific repository, owner, or file is identified anywhere in this post; every pattern described is a generalization across multiple apps, not a quote from one.

The takeaway is not that Cursor writes insecure code. It writes good code. The takeaway is the same one every one of these studies lands on: the security of an AI-assisted app is decided by the human review the code still needs, and that need doesn't shrink as the tools get better. The tool got better. The part that leaks secrets is still us.

Prbl scans the AI-generated parts of your codebase for exactly the kinds of issues above.

Find what AI missed — free
We Scanned 120 Web Apps Built With Cursor. Is Cursor-Generated Code Secure?: Prbl