In May 2023, Toyota disclosed that an access key had been sitting in a public GitHub repository since December 2017 — nearly five years — exposing the T-Connect service's customer database and up to 296,019 vehicle owners' data. The key wasn't stolen through a sophisticated exploit. It was hardcoded into source code, pushed to a public repo, and left there. Toyota is not an outlier. GitGuardian's 2024 State of Secrets Sprawl report found 12.8 million new secrets leaked in public GitHub commits during 2023 alone, a 28% jump from the year before, and its research consistently shows that once a secret is exposed, only a small fraction ever get revoked. This post covers what hardcoded secrets actually are, how they end up in production repos, how fast attackers find them, and the concrete steps — scanning, rotation, and prevention — that stop the leak before it becomes a breach.
What counts as a hardcoded secret, and why does it end up in a GitHub repo?
A hardcoded secret is any credential — an API key, database connection string, OAuth token, private key, or password — written directly into source code, config files, or commit history instead of being pulled from a vault or environment variable at runtime. It ends up in GitHub for mundane reasons: a developer hardcodes an AWS key to get a script running locally and forgets to remove it before committing; a .env file gets added by mistake because .gitignore wasn't updated; a Jupyter notebook or CI YAML file bakes in a Slack webhook or Stripe key for convenience during debugging. Samsung's 2019 internal source code leak is a well-documented example — the exposed repositories contained hardcoded AWS access keys, internal certificates, and SmartThings credentials that had been committed for developer convenience, not maliciously, but with real exposure once the repo went public. The pattern repeats because secrets management friction (vaults, IAM roles, secret injection) is real, and hardcoding is the path of least resistance under a deadline.
How common is secret exposure on GitHub right now?
It's common enough that GitHub itself scans every public push for known token patterns, and still finds hundreds of thousands of valid secrets a year. GitHub's own secret scanning partner program covered over 200 token types as of 2024 and, according to GitHub's 2023 Octoverse security data, flagged more than 1 million exposed secrets across public repositories that year. A 2019 North Carolina State University study ("How Bad Can It Git?") that scanned live GitHub traffic found roughly 100,000 repositories leaking at least one secret on a given day, with thousands of new secrets published every 24 hours — and follow-up research from the same group confirmed the volume has only grown as commit velocity increased. The most frequently leaked types, consistently across GitGuardian's and GitHub's datasets, are cloud provider keys (AWS, GCP, Azure), generic API keys, database connection strings, and OAuth/session tokens — the exact credentials that grant direct access to production infrastructure, not just test environments.
How fast do attackers exploit a leaked secret?
Fast enough that manual review is not a viable control — automated scanning bots pick up newly pushed AWS keys and attempt to use them within minutes of the commit landing on GitHub. The NC State honeypot study planted deliberately leaked AWS credentials in public repos and measured first-use times as short as a few minutes, with most leaked keys attracting exploitation attempts within a few hours. This is because credential harvesting on public source hosting is largely automated: bots continuously clone new commits, regex-match against known token formats (AWS AKIA..., Slack xox..., Stripe sk_live_..., GitHub PATs ghp_...), and immediately test validity against the corresponding provider's API. That window — between a git push and the first automated probe — is typically measured in minutes, which means detection has to happen at commit time or in near-real-time CI, not during a quarterly audit.
How do you find hardcoded secrets already sitting in your repo history?
You run a dedicated secret-scanning tool against the full commit history, not just the current branch tip, because a secret removed in a later commit is still readable in the diff of the commit that introduced it. Tools like Gitleaks, TruffleHog, and GitHub's own secret scanning use regex and entropy-based detection to walk every commit in a repository's history and flag matches — TruffleHog additionally verifies many credential types live against the issuing provider's API, so a scan tells you not just "this looks like an AWS key" but "this AWS key is still active." Running gitleaks detect --source . -v or trufflehog git file://. --since-commit HEAD~500 against a repo commonly surfaces credentials that were committed and "removed" years earlier — Toyota's five-year exposure window is the norm for this class of finding, not the exception, because deleting a file in a new commit does nothing to the Git objects still reachable from history. Any full audit needs to include forks, archived repos, and CI logs, since secrets frequently leak through build output or debug logging rather than the source tree itself.
How do you stop new secrets from ever being committed?
You block the commit before it leaves the developer's machine or hits the shared branch, using pre-commit hooks and pipeline gates rather than relying on after-the-fact scanning. Pre-commit tools (git-secrets, Gitleaks' pre-commit hook, or GitHub's push protection, which became generally available for all public repos in 2023 and for private repos on GitHub Advanced Security in 2024) reject a git push outright when a known secret pattern is detected, forcing rotation before the credential ever reaches a remote. That has to be paired with a secrets management practice — short-lived credentials via a vault (HashiCorp Vault, AWS Secrets Manager, cloud IAM roles) instead of static keys — because a scanner only catches what regex patterns and entropy checks expect, and a rotated, short-lived token limits blast radius even if detection is delayed. Teams that combine push protection with mandatory secret rotation on any confirmed exposure cut their mean time to remediation from the industry-typical weeks (GitGuardian reports many exposed secrets remain valid 60+ days after detection) down to hours.
How Safeguard Helps
Safeguard's Griffin AI engine scans every commit and pull request for hardcoded secrets alongside dependency and configuration risk, correlating each finding with reachability analysis so security teams see whether an exposed credential actually guards a live, exploitable path rather than dead code or a decommissioned test fixture. Safeguard generates and ingests SBOMs across your repositories to map exactly which services and packages a leaked secret's blast radius touches, so triage starts with "what does this key actually unlock" instead of a flat severity score. When a secret is confirmed live, Safeguard opens an auto-fix pull request that strips the credential from source, wires in environment-variable or vault-based injection, and flags the exposed value for rotation — turning a five-year Toyota-style exposure window into a same-day fix reviewed directly in your existing PR workflow.