{"slug": "why-deleting-a-hardcoded-secret-does-not-fix-it-cwe-798", "title": "Why Deleting a Hardcoded Secret Does Not Fix It (CWE-798)", "summary": "A developer found that AI coding assistants like Cursor frequently generate code with hardcoded secrets, such as live Stripe API keys, because the models are trained on example code that inlines credentials. The developer warns that deleting a secret from a file does not fix the issue, as it remains in git history, and recommends loading secrets from environment variables, using .gitignore, and running secrets scanners like gitleaks as pre-commit hooks.", "body_md": "I asked Cursor to wire up Stripe in a side project last week. It gave me working checkout code in about ten seconds. It also gave me this on line 3:\n\n``` js\nconst stripe = require('stripe')('sk_live_51H8xY2eZvKYlo2CaBq...');\n```\n\nThat is a live secret key, sitting in a file I was about to commit. Not a placeholder, not a `TODO`\n\n, an actual formatted key. The AI didn't flag it. It read like a normal line of setup code, which is exactly why it's dangerous.\n\nThis is the most common thing I catch in AI-generated code, and it's almost never the developer being careless. It's the tool doing what its training taught it to do.\n\nA hardcoded secret is any credential written directly into source instead of loaded from the environment at runtime. AI editors produce them constantly:\n\n``` js\n// What Cursor generated\nconst stripe = require('stripe')('sk_live_51H8xY2eZvKYlo2C...'); // CWE-798\nconst JWT_SECRET = 'my-super-secret-key-123';\nconst db = mysql.createConnection({\n  host: 'prod-db.internal',\n  user: 'admin',\n  password: 'Sup3rSecret!2024'\n});\n# Same pattern in Python\nAPI_KEY = \"sk-proj-abc123def456...\"  # CWE-798\nDATABASE_URL = \"postgres://admin:hunter2@prod-db:5432/app\"\n```\n\nEvery one of these is a working credential. The problem isn't just that it's visible. It's that once you `git commit`\n\n, the secret is in your history permanently, even if you delete the line in the next commit. Anyone who ever clones the repo, or reads a leaked mirror of it, gets the key.\n\nAI editors hardcode secrets because the code they trained on is overwhelmingly example code, and example code inlines fake secrets to stay self-contained. Every Stripe quickstart, every JWT tutorial, every \"connect to your database in 5 minutes\" blog post drops a literal string in for the key so the snippet runs as-is. The model learned that \"set up an API client\" means \"put a key-shaped string right here.\"\n\nThe model has no concept of which strings are safe to show and which ones guard money or data. To the generator, `sk_live_...`\n\nand `\"hello world\"`\n\nare just tokens that fit the slot. It also can't see your `.env`\n\nfile or know your deployment setup, so inlining is the path of least resistance that always produces runnable code.\n\nThat's the trap: the output runs perfectly. Nothing errors. The vulnerability is invisible until the repo leaks, and by then the key has been in your history for months.\n\nLoad every secret from an environment variable, and never let a raw credential enter a tracked file. Two lines change:\n\n``` js\n// Fixed\nconst stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);\nconst JWT_SECRET = process.env.JWT_SECRET;\nconst db = mysql.createConnection({\n  host: process.env.DB_HOST,\n  user: process.env.DB_USER,\n  password: process.env.DB_PASSWORD\n});\npython\n# Fixed\nimport os\nAPI_KEY = os.environ[\"OPENAI_API_KEY\"]\nDATABASE_URL = os.environ[\"DATABASE_URL\"]\n```\n\nThen three things make it stick. Add `.env`\n\nto your `.gitignore`\n\nbefore you write a single secret. Run `gitleaks`\n\nas a pre-commit hook so a stray key blocks the commit instead of sailing into history. And if a real key ever did get committed, rotate it, don't just delete the line. Deleting a secret from the current file leaves it fully intact in every prior commit, so the only safe move after exposure is to revoke the old key and issue a new one.\n\n**Q: Is a hardcoded secret still a problem if my repo is private?**\n\nA: Yes. Private repos get cloned to laptops, mirrored to CI systems, forked, and occasionally made public by mistake. Treat any secret in git history as compromised the moment it's committed, regardless of repo visibility.\n\n**Q: If I delete the hardcoded key in a later commit, am I safe?**\n\nA: No. Git keeps full history, so the secret is still readable in the earlier commit. The only safe response to a committed secret is to rotate it, revoke the old value, and issue a new one.\n\n**Q: How do I catch this before it gets committed?**\n\nA: Run a secrets scanner like gitleaks as a pre-commit hook, and keep a `.env`\n\nfile in `.gitignore`\n\n. That combination stops a key from ever reaching a tracked file, which is far easier than cleaning it out of history later.\n\nI've been running [SafeWeave](https://safeweave.dev/blog/why-deleting-a-hardcoded-secret-does-not-fix-it-cwe-798) for this. It hooks into Cursor and Claude Code as an MCP server and flags hardcoded secrets before I move on, using a gitleaks-based scanner that runs the moment code is generated. Even a basic pre-commit hook with semgrep and gitleaks will catch most of what's in this post. The important thing is catching it early, whatever tool you use.\n\nRead the full original on the SafeWeave blog: [https://safeweave.dev/blog/why-deleting-a-hardcoded-secret-does-not-fix-it-cwe-798](https://safeweave.dev/blog/why-deleting-a-hardcoded-secret-does-not-fix-it-cwe-798)", "url": "https://wpnews.pro/news/why-deleting-a-hardcoded-secret-does-not-fix-it-cwe-798", "canonical_source": "https://dev.to/c_k_fb750e731394/why-deleting-a-hardcoded-secret-does-not-fix-it-cwe-798-1bp1", "published_at": "2026-07-31 19:38:33+00:00", "updated_at": "2026-07-31 19:41:54.836559+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-tools", "ai-safety", "developer-tools"], "entities": ["Cursor", "Stripe", "gitleaks", "CWE-798"], "alternates": {"html": "https://wpnews.pro/news/why-deleting-a-hardcoded-secret-does-not-fix-it-cwe-798", "markdown": "https://wpnews.pro/news/why-deleting-a-hardcoded-secret-does-not-fix-it-cwe-798.md", "text": "https://wpnews.pro/news/why-deleting-a-hardcoded-secret-does-not-fix-it-cwe-798.txt", "jsonld": "https://wpnews.pro/news/why-deleting-a-hardcoded-secret-does-not-fix-it-cwe-798.jsonld"}}