
26,400 live credentials found scanning 7.25M repos on China's Gitee
This guest post by independent security researcher Ben Zimmermann was developed in collaboration with the Kingfisher team at MongoDB. Ben specializes in large-scale credential exposure research across public source-host…
以下正文同步自 Hacker News,版权归原站所有,已转换为易读排版。
This guest post by independent security researcher Ben Zimmermann was developed in collaboration with the Kingfisher team at MongoDB. Ben specializes in large-scale credential exposure research across public source-hosting platforms.
TL;DR: I scanned 7,256,531 public repositories on Gitee (China's largest indigenous Git hosting platform), using both TruffleHog and Kingfisher, and found 26,400 unique verified-live credentials. Findings included an active organization-admin credential for a major enterprise AI platform and thousands of live cloud provider access keys.
Gitee, launched in 2013 by OSChina, was selected by China's Ministry of Industry and Information Technology as the country's national open-source code hosting platform. Its public API is severely constrained relative to GitHub and GitLab: no paginated projects endpoint, and the on-site code-search feature appears to have been retired years ago. A 2021 attempt to study credential exposure on Gitee concluded that its APIs were too limited to scale the research.
Like any large Git platform, it's an attractive surface for credential exposure:
It is Git-based, so secrets buried deep in commit history persist.
It hosts millions of public repositories with active commit volume.
It has no public equivalent of the platform-vendor secret-scanning partnerships that have become standard on GitHub.
Gitee's public API is severely limited, so enumerating millions of repositories required combining many surfaces: the only official REST endpoint that returned useful data at scale, the platform's Explore feed, per-user repository and stargazer pages on the website itself, and Gitee's internal Elasticsearch widget that backs the on-site search UI.
The single official REST endpoint that returned useful data at scale was GET /api/v5/search/users?q=. I hit it with three-character prefix queries (aaa, aab, ..., zzz) and combined the results with usernames extracted from the public Explore feed (/explore/all?order=starred|popular|updated). I then expanded that set via each user's following list and the stargazers of popular repositories. This produced a seed corpus of 1,704,759 usernames.
With the username corpus in hand, two per-user pages yielded repositories: gitee.com/{user}/projects (a user's own repos) and gitee.com/{user}/stared_projects (repos the user has starred). Page 1 of /projects returns full HTML; subsequent pages are AJAX-paginated (X-Requested-With: XMLHttpRequest). The stargazer-list pages used during username bootstrap paginate the same way, additionally requiring a CSRF token extracted from the page-1 HTML.
A large fraction of the platform sits outside the social graph. To reach it, I used the same internal Elasticsearch endpoint that backs Gitee's on-site search UI: so.gitee.com/v1/search/widget/wong1slagnlmzwvsu5ya. It takes a query ID, a q parameter, and pagination via from + size:
Each query returned at most 20 results per page, with a hard cap of 200 results total (from + size <= MAX_RESULTS) regardless of how many matches actually existed. For specific usernames, this was usually fine; for common usernames and trigram prefix queries against the widget, the cap silently truncated results.
The widget's response includes Elasticsearch aggregations that bucket results by language (编程语言) and license (许可证). For the per-username scrape, when a query was capped, I split it by the language buckets the response already returned:
For trigram prefix queries against the widget (used to surface repos not associated with any user I'd discovered), I extended this into a BFS over a query tree: capped nodes split first by language, then by license, then by deeper prefix until each branch fit within 200 results.
After deduplicating repo IDs across all sources, this produced a working set of 7,256,531 unique public Gitee repositories.
The next challenge was cloning and scanning the 7.25 million repositories. To do this in a single Python script, I used Modal, a serverless compute platform popular for AI workloads but well-suited to most parallel jobs. I ran TruffleHog and Kingfisher concurrently against every repository for increased coverage. Each surface verified credentials that the other missed, so running both caught more exposed credentials than either alone.
Figure 1. Dual-scanner pipeline architecture.
The container image is a multi-stage build that pulls both scanner binaries from their upstream releases into a single Python base, plus git and OpenSSH for cloning:
The per-repo scan function
A single Modal function bare-clones each repo over SSH and runs both scanners concurrently as subprocesses against the same on-disk clone:
Dispatching 7.25M repos in batches
I split the corpus into 50 batches of ~150K repos and ran them sequentially at a steady 350 concurrent containers. Smaller batches were safer at this scale and easier to resume after interruptions; running larger batches was unstable and would hit clone-side blocks.
Total wall time: roughly one month of continuous execution. Per-repo clone times were a major contributor: Gitee's servers sit in China, and cross-Pacific network distance plus SSH protocol overhead made each clone materially slower than an equivalent GitHub clone would be. The total cost was $3,097.64, fully absorbed by the $5,000 compute-credit sponsorship from Modal that supported this research. The same Modal + dual-scanner architecture works against most Git hosts with little more than a clone-URL substitution. I used a smaller-scale version of this approach in a prior investigation of Algolia DocSearch admin keys.
Across the 7,256,531 public Gitee repositories scanned, the dual-scanner pipeline surfaced 26,400 unique, verified-live credentials after deduplicating by token value.
Both scanners authenticate each candidate against its vendor's API at scan time (TruffleHog's --only-verified and Kingfisher's --only-valid modes), discarding anything that pattern-matches but fails to authenticate. The 26,400 figure is deduplicated by raw secret value, so duplicates across repositories or scanners count once.
Either scanner alone would have caught only about half of these credentials. The two tools' detector coverage was largely complementary: TruffleHog dominated Alibaba Cloud key detection (9,428 vs. 993), while Kingfisher dominated DeepSeek (2,940 vs. 230), OpenAI (1,198 vs. 150), HuggingFace (154 vs. 1), and Chinese-AI services like Zhipu (1,489 vs. 0) that TruffleHog has no detector for.
The single most common leaked credential type was Alibaba Cloud AccessKey pairs: roughly 1 in every 766 Gitee repositories contained a verified-live Alibaba Cloud credential.
A long tail of additional vendors (LangSmith, OpenWeather, Algolia, PostHog, OpenRouter, MySQL, Stripe, Slack, Twitter, and others) accounts for the rest.
The vast majority of verified-live credentials were committed in the last two years. 2025 alone accounts for 12,242 unique credentials, nearly half the entire dataset.
Figure 3. Unique credentials committed by year.
Most credentials were committed from personal mail services (qq.com, 163.com, gmail.com), making per-company attribution impossible at scale. The corporate-domain numbers below are a floor; even so, the names span major Chinese and Western tech companies alike.
Figure 5. Unique credentials by committer email domain.
Smaller corporate footprints also appear from Oracle, Apple, Meta, Anthropic, and others, plus Chinese commercial and academic domains.
The closest prior data points come from TruffleSecurity's scan of 5.6 million public GitLab repositories, and a companion Bitbucket scan referenced in that post.
Gitee tops both Western platforms on raw count and per-repository density. One methodology note: the TruffleSecurity scans used TruffleHog alone, while this one used TruffleHog and Kingfisher together. TruffleHog's detector library skews toward Western vendors, and Gitee has heavy Chinese-vendor activity (Alibaba Cloud, DeepSeek, Zhipu, and others) that Kingfisher's coverage helps to surface; stripping our findings to TruffleHog-only puts Gitee at 1.76 per 1,000 repos.
I emailed the vendors with the highest exposure volume in this scan, providing each a coordinated report containing the full list of verified-live credentials associated with their service, along with source-repository metadata to help them attribute affected customers.
Per-developer notification (contacting the committer of each leaked credential individually) was not pursued at this scale. Vendor-side revocation is the more reliable path, since it doesn't require any action from the user who leaked the credential.
At the time of writing, revocation status for the disclosed credentials has not yet been confirmed.
Gitee is a meaningful credential-exposure surface. 26,400 verified-live credentials across 7.25M repositories. Per-repository density higher than comparable published scans of GitLab and Bitbucket.
Major tech companies appear in the committer metadata, Chinese and Western alike. The breadth includes Huawei, ByteDance, Google, Microsoft, Oracle, and others, suggesting this is not a purely-Chinese-developer phenomenon.
Disclosure paths are asymmetric. Western companies typically have bug bounty programs or accessible security channels. Most Chinese companies don't, leaving leaked credentials without a clear remediation path.
The architecture is portable. The same Modal + dual-scanner pipeline works on most Git hosts with little more than a clone-URL substitution; the full scan cost roughly $3,000.
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。