More than 543,000 credentials exposed in public GitHub repositories were still valid when researchers tested them in July, according to a report covered by BleepingComputer — even though the platform has spent years building safeguards meant to catch exactly this kind of accidental leak.
The number matters less for its size than for what it represents: over half a million times, someone pushed a working key, token or password into a repository the whole world could read, and the leak went uncorrected long enough to be tested and still authenticate. BleepingComputer did not publish the researchers' validation methodology in its coverage, so the precise conditions behind the "still valid" label should be read with that caveat in mind.
What is not in doubt is the pattern. Public repositories remain one of the most reliable sources of live credentials in the security industry, and the leak rate has not obviously fallen despite years of tooling, warnings and platform-level safeguards.
What GitHub already does — and why it isn't enough
GitHub layers two mechanisms on top of the platform. Secret scanning inspects repositories for well-known secret patterns — API keys, cloud credentials, database connection strings — and alerts publishers when one turns up. Push protection goes further, attempting to stop a secret from ever reaching the repository in the first place.
Both are real, and both are more widely available than most teams assume: secret-scanning alerts and push protection are free for public and private repositories alike, with push protection auto-enabled on new public repos. The features that sit behind GitHub's paid Advanced Security tier are the custom patterns, deeper code scanning and audit tooling — not the basic detection and blocking layer.
That framing matters more than it sounds. Secret scanning is a detection control, not a prevention control. It tells you a credential has already been exposed. Whether anyone acts on that alert is a human question — and 543,000 still-valid credentials suggest that, at scale, many people do not.
Why developers keep leaking secrets
The mechanisms are mundane and well documented. Configuration files get committed alongside application code. .gitignore entries are added after the fact rather than before the first commit. Test environments reuse production credentials "temporarily." Forks and mirrors propagate a leak far beyond the original repository, extending the blast radius with every clone.
And history is the trap people forget. Deleting a secret-bearing file from the current branch does nothing to remove it from the commit log, which remains readable by anyone who clones the repository. The worst outcome in security is the "cleaned up but not rotated" state — one that hides the visible warning while leaving the credential live and usable.
What developers should change
The remediation sequence is not complicated, but it is unforgiving of shortcuts.
Rotate first, delete second. If a secret has ever been public, treat it as compromised regardless of how quickly the offending commit is reverted. Rotation invalidates the old credential; deletion only hides it. Any response plan that leads with deletion rather than rotation has missed the point.
Scan before you push. Pre-commit hooks and local secret-scanning tools — gitleaks, trufflehog, detect-secrets and similar utilities — can catch most accidental leaks at the developer's machine, where the context is still fresh and the fix is trivial.
Check history, not just the current tree. This is the blind spot most teams have. Scanning the working directory misses secrets buried in past commits, and no amount of cleanup in the present fixes a credential sitting in the repository's log. Only tools that walk commit history — gitleaks and trufflehog both support it — surface this class of exposure.
Treat rotation as routine, not incident response. Credential rotation should be a scheduled, low-friction operation. If rotating a key is painful, teams will not do it until an incident forces their hand.
The wider lesson
None of this is a tooling gap in the strict sense. The tools exist, many of them are free, and the detection layer is already wired into the platform. What remains is a process problem — an alert that lands in a queue nobody works, or a rotation nobody owns.
For organisations handling personal data, credentials in public repositories also carry regulatory weight. Under Hong Kong's Personal Data (Privacy) Ordinance, organisations bear responsibility for safeguarding personal data against unauthorised access, and a leaked database or cloud credential can be an indirect route to exactly that. Smaller teams, which often run lean security functions and lack licences for GitHub Advanced Security, are disproportionately exposed to both the risk and the cost of response.
Reducing the next figure of half a million will not be automated work. It is cultural and procedural — the part of security that no scanner can do for you.
據 BleepingComputer 報導的一份研究報告,超過 54.3 萬組在公開 GitHub 倉庫中暴露的憑證,於七月經研究人員測試後仍然有效——儘管該平台多年來一直致力搭建保障機制,目的正是阻止這類意外洩露。
這個數字的重要性不在於其規模,而在於它所代表的意義:超過五十萬次,有人把一組可用的 key、token 或密碼推入了一個全世界都能讀取的倉庫,而且洩露持續了足夠長的時間,長到可以被測試並仍能通過驗證。BleepingComputer 在其報道中並未公開研究人員的驗證方法,因此「仍然有效」這一標籤背後的具體條件,讀者宜考慮此 caveat 來理解。
毋庸置疑的是這個模式。公開倉庫至今仍是保安業界最可靠的即時憑證來源之一,儘管多年來各種工具、警告和平台層級的防護措施不斷推出,洩露比率並未有明顯下降。
GitHub 已有的措施——以及為何仍然不夠
GitHub 在平台之上疊加了兩項機制。Secret scanning 會檢查倉庫中是否存在已知的 secret 模式——如 API key、雲端憑證、database connection string——一旦發現便會向發布者發出警報。Push protection 則更進一步,試圖在 secret 到達倉庫之前就將其攔下。
兩者都是真實存在、而且比大多數團隊想像中更為普及:secret-scanning alerts 和 push protection 對公開及私人倉庫同樣免費提供,而新建立的公開倉庫更會自動啟用 push protection。真正需要 GitHub 付費 Advanced Security 層級才有的功能,是 custom patterns、更深入的 code scanning 以及審計工具——而非基本的偵測和阻擋層。
這個框定的重要性遠超表面所見。Secret scanning 是一項偵測性控制(detection control),而非預防性控制(prevention control)。它告訴你的是一組憑證已經被暴露。是否有人會就該警報採取行動,這是人為的問題——而 54.3 萬組仍然有效的憑證表明,在大規模情況下,許多人並沒有這樣做。
開發者為何不斷洩露 secrets
背後的機制平淡無奇,且已有充分記錄。設定檔與應用程式碼一併被 commit 進版本控制。.gitignore 的項目往往是事後才補上,而非在第一次 commit 之前就加好。測試環境「暫時」沿用生產環境的憑證。Fork 和 mirror 更會令一次洩露遠遠傳播至原始倉庫之外,每多一次 clone,blast radius 就隨之擴大。
而 commit history 是最常被忘記的陷阱。從當前分支刪除一個載有 secret 的檔案,並不能把它從 commit log 中移除,任何 clone 該倉庫的人依然可以讀取。保安領域最壞的情況,就是「已清理但未轉換鑰匙」的狀態——表面上的警告消失了,但該憑證依然存活且可用。
開發者應作出的改變
修補的先後次序並不複雜,但不容許走捷徑。
先轉換(rotate),後刪除(delete)。 如果一組 secret 曾經公開過,不論犯事的 commit 多快被 revert,都應將其視為已遭洩露。Rotation 會令舊的憑證失效;刪除只是將其隱藏。任何以刪除而非 rotation 為首要步驟的應變計劃,都已經錯失了重點。
Push 之前先掃描。 Pre-commit hook 及本地 secret-scanning 工具——如 gitleaks、trufflehog、detect-secrets 及類似的工具——可以在開發者自己的機器上攔截大部分意外洩露,因為在那裡上下文仍然清晰,修正亦是舉手之勞。
檢查 commit history,而不只是當前的 tree。 這是大多數團隊的盲點。掃描 working directory 會遺漏埋藏在過去 commit 中的 secrets,而無論現在進行多少清理,都修補不了靜靜躺在倉庫 log 中的一組憑證。只有能遍歷 commit history 的工具——gitleaks 和 trufflehog 均支持——才能讓這類暴露浮現出來。
將 rotation 視為日常工作,而非事故應變。 Credential rotation 應該是一項有既定安排、低摩擦的操作。如果轉換一組 key 令人痛苦,團隊就會一直拖着,直到事故迫使其行動。
更廣泛的啟示
以上種種在嚴格意義上並非工具上的缺失。工具已經存在,其中許多是免費的,偵測層亦已接入平台。剩下的是一個流程問題——警報落入了無人處理的 queue,或者是一項無人負責的 rotation。
對於處理個人資料的機構,公開倉庫中的憑證亦帶有監管層面的影響。根據香港《個人資料(私隱)條例》,機構有責任保障個人資料免遭未經授權的存取,而一組洩露的 database 或雲端憑證,可以正是通往該等存取的間接途徑。規模較小的團隊往往保安人手精簡,亦缺乏 GitHub Advanced Security 的授權,在風險和應變成本兩方面都承受了不成比例的壓力。
要將下一次的數字由五十萬下降,不可能是自動化的工作。它關乎文化與流程——正是保安工作中,任何 scanner 都無法替你完成的部分。
