Hardcoded Secrets in Code: How to Find Them First
In 2016, attackers obtained credentials from a private GitHub repository used by Uber engineers and used them to reach an AWS datastore holding personal information on roughly 57 million riders and drivers. Uber’s handling of the disclosure made things worse, and the eventual settlement with US state attorneys general came to $148 million.
In 2022, Toyota disclosed that a piece of source code for its T-Connect service — containing an access key to a data server — had been sitting in a public GitHub repository for almost five years, potentially exposing the email addresses of roughly 300,000 customers.
These weren’t junior developers making rookie mistakes, and they weren’t exotic attacks. They were credentials in places credentials should never be, found by people who were looking. That’s the entire problem in one sentence: secrets committed to a repository will eventually be found, and the finder may not be you.
The scale is well documented. GitGuardian’s State of Secrets Sprawl reports have counted millions of new secrets exposed in public GitHub commits every year — north of ten million in a single year in recent editions. And researchers who deliberately publish canary AWS keys to public repositories consistently watch them get harvested and abused within minutes. Automated scrapers monitor the public commit firehose around the clock; the window between “pushed” and “exploited” is measured in minutes, not days.
How secrets sneak into repositories
Understanding how secrets end up in code is the first step toward preventing it:
1. The “quick test” trap
A developer needs to test something quickly, hardcodes a credential temporarily, gets distracted, commits, pushes, forgets. This is the single most common path — it’s a memory failure, not a competence failure, which is exactly why process beats vigilance.
2. The copy-paste accident
Example code from documentation or Stack Overflow contains placeholder credentials. The developer forgets to swap them out — or worse, swaps the placeholder for a real credential to “make it work” and commits the result.
3. The configuration mistake
Environment-specific config files that belong in .gitignore get committed anyway, carrying database connection strings, API keys, and service credentials with them.
4. The legacy migration
A team migrates an old codebase to git. Historical commits contain secrets from the era when “this is only used internally.” It isn’t internal anymore.
5. The false sense of privacy
Secrets go into a “private” repository. The project later gets open-sourced, a fork goes public, or repository permissions change — and every historical commit, secrets included, comes along for the ride.
That last point hides the most dangerous misconception in this whole topic: deleting a secret from the current code does not remove it from git history. Anyone who can clone the repository can read every version of every file ever committed. The only real fix for a committed secret is to rotate the credential itself.
Secrets are one symptom — the codebase has more
Hardcoded credentials are the most vivid example of a broader category: flaws that static analysis can catch before code merges. Assessments of real-world applications keep turning up the same families of weakness, year after year:
- Injection flaws (SQL injection and friends) — still among the most common findings in web-app assessments, and an OWASP Top 10 fixture for two decades.
- Cross-site scripting (XSS) — scripts injected into pages to steal sessions or hijack accounts.
- Insecure cryptography — broken algorithms like MD5 or SHA-1 still hashing passwords in production code.
- Path traversal — attackers reading files outside the intended directory.
- Insecure deserialization — capable of leading to remote code execution; folded into A08: Software and Data Integrity Failures on the OWASP Top 10 (2021).
- Server-side request forgery (SSRF) — your server tricked into making requests to internal systems, including cloud metadata endpoints that hand out credentials.
You’ll sometimes see precise prevalence percentages attached to each of these. We’ve dropped them — they’re rarely traceable to a real methodology. The qualitative point stands on its own: every sizeable codebase contains some of these, and humans reviewing pull requests will not catch them all.
Why the fix gets more expensive the longer you wait
The economics of application security come down to one curve: the cost of fixing a flaw rises steeply with every stage it survives.
Industry estimates have long put the cost of fixing a vulnerability found during development at a tiny fraction — often cited as one to two orders of magnitude less — of fixing the same flaw in production, and the gap to post-exploitation cleanup is wider still. The exact multipliers vary by study; the shape of the curve doesn’t. A flaw caught by a scanner in a pull request costs minutes of one developer’s attention. The same flaw in production costs change-management, hotfixes, and incident review. The same flaw exploited costs forensics, notification, regulators, and lawyers.
The public record makes the top of that curve concrete:
- Equifax (2017): a known-vulnerable Apache Struts component left unpatched — 147 million people affected, with total publicly reported costs well past $1.4 billion US.
- Capital One (2019): an SSRF weakness chained with a misconfigured firewall — about 100 million records, a $190 million class-action settlement plus an $80 million regulatory penalty.
- T-Mobile (2021–2023): repeated API security failures — tens of millions of records exposed, with settlements alone exceeding $350 million.
To be fair about scope: not every one of these was a flaw a static analyser would have flagged. Equifax was a dependency-patching failure, and Capital One was infrastructure misconfiguration chained with an application-layer weakness. The point isn’t “SAST would have saved them all” — it’s that application-layer weaknesses become nine-figure losses, and the cheap place to fight them is before deployment.
What automated secrets scanning actually does
This is where SAST — static application security testing — earns its place in the pipeline. A tool like SonarQube analyses source code without running it, on every commit and pull request, and applies rule sets that include dedicated secrets detection: hardcoded passwords, AWS-style access keys, API tokens, and other credential patterns.
Wired into a DevSecOps pipeline, the loop looks like this:
- Pre-commit: lightweight hooks (and IDE plugins) catch obvious secrets before they ever reach the repository — the cheapest possible save, because nothing has to be rotated.
- On every pull request: the SAST scan runs automatically and decorates the PR with findings — “hardcoded credential on line 47,” not a 200-page PDF.
- Quality gates: if the scan finds a secret or a critical vulnerability, the merge is blocked. Nobody has to remember to run anything, which is the entire point — Uber-style incidents are memory failures, and automation doesn’t get distracted by pizza.
- Continuously: the full codebase is re-analysed as rules improve, so yesterday’s clean bill of health doesn’t go stale silently.
SonarQube covers this alongside the broader SAST families above — injection, XSS, crypto misuse, and more — across 30+ languages, with IDE plugins and CI/CD integrations for the platforms you already use. What it doesn’t do is test your running application or audit third-party dependencies; for the honest scope-and-cost comparison against full enterprise suites, see SonarQube vs Veracode: DevSecOps at a Fraction of the Cost.
On value, we’ll skip the five-digit ROI percentages this genre is famous for. The modest, defensible version: a production-grade vulnerability costs thousands of dollars in engineering time to remediate even when it’s never exploited. A scanner that prevents a handful of those a year — never mind a single credential leak — more than covers a managed subscription.
FAQ
What happens if I commit an AWS key to GitHub?
If the repository is public, assume the key is compromised within minutes — automated scrapers monitor public commits continuously, and abuse (typically cryptomining on your account) follows fast. Rotate the key immediately, audit the account for unauthorised activity, and check whether the key’s permissions exposed anything beyond compute. AWS also scans public repositories and may quarantine exposed keys, but never rely on that safety net.
Does deleting a committed secret from git remove it?
No. Git history preserves every version of every file, so the secret remains readable to anyone who can clone the repository — and if it was ever public, assume it has already been copied. Rewriting history (with tools like git filter-repo) cleans your repository but does nothing about copies already harvested. The only real fix is to rotate the credential: the exposed secret must stop working.
Can SonarQube detect hardcoded secrets?
Yes. SonarQube ships secrets-detection rules covering hardcoded passwords and the credential patterns of major providers (AWS keys, API tokens, and similar), flagged during its normal static analysis of commits and pull requests. Many teams pair it with a pre-commit scanner (such as gitleaks) so obvious secrets are caught before they reach the repository at all — defence in depth applies to pipelines too.
What is SAST?
Static application security testing: automated analysis of source code, without executing it, to find security flaws — injection vulnerabilities, insecure cryptography, hardcoded secrets — as the code is written. Its counterpart DAST tests the running application from outside. SAST is the “shift-left” layer: it runs on every commit, so flaws are caught at the cheapest possible moment, before they ship.
Find your secrets first
Every day your repositories go unscanned is a day a forgotten credential sits in history waiting to be found. The fix is boring, automated, and cheap relative to literally any alternative.
Talk to us about managed SonarQube — we host, harden, integrate, and tune it, and your pull requests start telling you the truth. Email sales@thinsky.com or request a quote. Prefer to start from the outside? Run a free external security audit to see what’s already visible to attackers, or scope a penetration test for the running-application side that static analysis can’t reach.