DEV Community

Davi
Davi

Posted on Originally published at blog.mago.team

GitHub Recon: How Public Repositories Expose Infrastructure, Credentials, and Identity

Before writing the exploit, the attacker scans the org. In under ten minutes, trufflehog github --org=target --only-verified returns contributor emails, deploy hostnames, and AWS credentials confirmed as active. No authentication. No technical vulnerability exploited.

An organization's GitHub presence is simultaneously its most public and least protected attack surface. Every commit exposes contributor identity, every workflow file reveals infrastructure topology, and every secret accidentally pushed stays in git history even after removal. GitGuardian 2025 puts numbers to the consequences: 12.8 million new secrets detected on GitHub in 2024, 35,000 commits per day containing credentials, median 94 days to effective remediation.

Git History Is Permanent Until Proven Otherwise

git rm creates a new commit that removes the file from the working tree, but leaves all previous git objects intact in the repository's object store. Running git log --all -- .env recovers every version of the file, including the ones the team believes it permanently deleted. Any clone made before the removal retains the full object, regardless of any subsequent action on the remote repository.

GitHub's CDN caches blobs and diffs at permanent URLs that remain accessible even after a force-push or branch deletion. Pack files stay on the servers until a manual request to GitHub support — a process that takes days to weeks to complete. Rewriting local history with git-filter-repo fixes only the origin repository; distributed clones made before the rewrite retain the deleted objects for up to 90 days via the default reflog.

GitGuardian 2025 puts the median at 94 days between secret detection and effective remediation. AquilaX documents that 70% of secrets remain valid even after a developer performs a rotation — the git log still contains them, and rotating without scrubbing history does not close the exposure. That window exists because teams treat rotation as a cleanup task for later, not as the first mandatory action when a leak is detected.

The correct sequence is to revoke the secret immediately, before any history rewrite. Rewriting history with the secret still active is cosmetic cleanup: any attacker who found it retains access throughout the entire process.

Workflow Files as Infrastructure Maps

.github/workflows/*.yml files are rarely classified as sensitive assets, but a typical deploy workflow exposes environment names (staging, production, us-east-1-prod), cloud regions, internal service hostnames, Docker registry URLs, and K8s cluster names. GitHub documents that environment names in public repositories are visible on the Deployments tab to any visitor, on all plans. Environment variables inside run: steps frequently include cloud account IDs, database endpoints, and internal service naming patterns.

HackerOne #1580567, reported against Glovo in May 2022, started with recon on the public org's workflow files. The files exposed internal service hostnames and API URL patterns; the researcher confirmed active AWS, MySQL, and Sendgrid credentials in the repository. HackerOne #766346, against Rocket.Chat, followed the same pattern: API keys hardcoded in configuration files inside a public org repository.

The tj-actions/changed-files supply chain attack in March 2025 compromised over 23,000 repositories because the attackers understood the structure of their victims' workflows. They knew exactly which secrets would be written to GitHub Actions logs when the action was compromised — intelligence derived directly from recon on the public workflows themselves.

To enumerate repositories and scan workflows across an org:

gh api /orgs/{org}/repos --paginate | jq '.[].name'
trufflehog github --org=<target> --only-verified
Enter fullscreen mode Exit fullscreen mode

The second command scans the full history of all public repositories, verifies each credential found against the providers' APIs, and returns only the active ones. The enumeration requires no authentication and is indistinguishable from legitimate GitHub API traffic.

Contributor Enumeration via Commit Metadata

Every git commit embeds author.name and author.email in the object. The GitHub API exposes those fields for every commit in public repositories without authentication, via pagination of /repos/{owner}/{repo}/commits. Enumerating commits across an entire org produces a structured employee directory: real name, corporate email, and internal username convention.

The corporate email format reveals the organization's SSO pattern. firstname.lastname@company.com confirms the login format, which can be tested against M365 portals, Okta, or any publicly exposed federated service. Employees who contribute to upstream projects from private repositories frequently expose their corporate emails in commits on public forks or open PRs against third-party repositories.

The GitHub public API also returns public organization members via /orgs/{org}/members. Members with private profiles are excluded from that list, but public commits and forks re-expose them indirectly. Gitrob and Octosuite automate org-level enumeration: they clone all repositories, iterate commit history, and identify corporate email patterns and sensitive file types. The resulting map connects employees to systems based on which repositories each email address appears in.

In the Samsung case, credentials were traced back to specific developers through commit metadata. Lapsus$ used that mapping to correlate which employees had access to the compromised backend systems and direct the subsequent lateral movement.

Samsung and Lapsus$: 6,695 Secrets in Code That Was Supposed to Be Internal

In February 2022, Lapsus$ accessed Samsung's internal GitHub Enterprise repositories and published 190 GB of source code. GitGuardian scanned the leaked material and found 6,695 secrets, including Samsung account backend credentials and AWS keys for internal services. The case documents a recurring mental model failure: teams treat internal GitHub as a secure environment and apply less rigor than they would to directly exposed production systems.

Private GitHub Enterprise repositories have an attack surface that includes every collaborator with access, every personal access token created by those collaborators, every connected CI pipeline, and any third-party integration with read permission configured. Lapsus$ did not exploit a technical vulnerability in GitHub; they used a compromised employee's credentials to enter the repositories. The code sitting there was the same kind of code that exists in public repositories of organizations without preventive controls.

The difference between the Samsung case and an organization with public repositories is that public repositories are accessible without compromising any collaborator first. The entry vector is GitHub itself — no social engineering or prior credential compromise required.

Remediation Starts at the Commit, Not at Detection

Post-push detection is a late response. TruffleHog verifies an AWS key against Amazon's API within seconds of the commit going public. With a median of 94 days to remediation, the attacker operates for an entire quarter before the organization revokes the secret. The only response that closes that window is prevention at the point of origin.

A pre-commit hook with gitleaks or detect-secrets blocks the push before the secret ever leaves the developer's machine:

# Install gitleaks as a pre-commit hook
gitleaks install
# Or via the pre-commit framework
pip install pre-commit detect-secrets
pre-commit install
Enter fullscreen mode Exit fullscreen mode

GitHub Advanced Security provides native protection upstream of the local defense line: push protection blocks pushes containing recognized secrets before they reach the server — free for public repositories since 2023. GitHub's native secret scanning has been available without configuration for all public repositories since 2022. Both layers operate without pre-commit hooks on the developer's machine, making them relevant even for teams that do not control every collaborator's local setup.

git-secrets installed at the org level standardizes prevention across all repositories without relying on individual developer configuration. Branch protection with required status checks blocks merges unless the secret-scanning check passes in CI. To identify what is already exposed in existing history:

trufflehog git file://. --only-verified
Enter fullscreen mode Exit fullscreen mode

GitGuardian 2025 documents 12.8 million new secrets on GitHub in 2024, with 35,000 daily commits containing credentials. Those numbers describe organizations that treat detection as a substitute for prevention.

Git history is permanent, workflows are public infrastructure maps, and commit metadata forms an unintentional employee directory. The only defensible position is intercepting the secret before the push; 94 days later, that window has already been exploited.

Top comments (0)