While building a Java REST API on my Linux (Fedora) machine, I noticed something bizarre on my GitHub repository page: right next to my profile picture in the Contributors sidebar, there was an unknown user (@wroc), whose account was created back in 2015 and had no recent activity.
The most intriguing detail? My local hostname/username on Fedora when I first initialized the project was wroc.
That coincidence triggered a few architecture and security questions:
- How did a user who never had access to my repository officially appear as a code contributor?
- If their account was linked to the commit, did GitHub's backend return real account metadata in the API response without their authentication?
- How far does this behavior go if I intentionally test it against another account?
This article documents my step-by-step investigation—inspecting raw Git objects, dissecting GitHub REST API JSON payloads, decoding Base64 Global Node IDs, and running a practical Proof of Concept (PoC).
1. Inspecting the Raw Git Object (git cat-file)
The first step was checking what was actually recorded locally in the repository's initial commits (specifically commit b1a5ca0).
To inspect the raw payload that Git sends over the wire during a git push, without any UI formatting, we use git cat-file -p:
git cat-file -p b1a5ca0 The output is surprisingly simple:
tree d3e2ab9087f6ccb4a141f7d368711233f879867d author wroc <wroc@users.noreply.github.com> 1790719762 -0300 committer wroc <wroc@users.noreply.github.com> 1790719762 -0300 chore: initialize project structure and IDE configurations When you run git commit, Git operates 100% offline. It makes no network requests, verifies no SSH keys, and does not validate whether you actually own that email address. It simply writes a plain-text string inside .git/objects/. At the time, my local Git config combined my Fedora hostname (wroc) with GitHub's noreply domain (wroc@users.noreply.github.com).
So what happens when we push this plain-text object to GitHub's servers via a git push authenticated with my own SSH key (lipebackend)?
2. What Does GitHub's API Return in the Response?
Querying GitHub's REST API directly for that specific commit:
curl -sL https://api.github.com/repos/lipebackend/api-rest/commits/b1a5ca0 We get the following JSON payload back from GitHub's backend:
{ "sha": "b1a5ca0edc8b69be88b91a67b4bd5d63543b8f90", "node_id": "C_kwDOUzptmtoAKGIxYTVjYTBlZGM4YjY5YmU4OGI5MWE2N2I0YmQ1ZDYzNTQzYjhmOTA", "commit": { "author": { "name": "wroc", "email": "wroc@users.noreply.github.com", "date": "2026-09-29T22:09:22Z" }, "committer": { "name": "wroc", "email": "wroc@users.noreply.github.com", "date": "2026-09-29T22:09:22Z" }, "message": "chore: initialize project structure and IDE configurations", "verification": { "verified": false, "reason": "unsigned", "signature": null, "payload": null } }, "author": { "login": "wroc", "id": 11420820, "node_id": "MDQ6VXNlcjExNDIwODIw", "avatar_url": "https://avatars.githubusercontent.com/u/11420820?v=4", "url": "https://api.github.com/users/wroc", "html_url": "https://github.com/wroc", "repos_url": "https://api.github.com/users/wroc/repos", "type": "User", "user_view_type": "public", "site_admin": false } } Looking closely at this API response raises three fascinating software engineering and security questions:
- I only pushed a plain-text string (
wroc@users.noreply.github.com), yet GitHub's server returned a full"author"object containing the user's real internal database ID (11420820), theiravatar_url, and a Base64-encodednode_id(MDQ6VXNlcjExNDIwODIw). - When querying the user's public profile at
[https://api.github.com/users/wroc](https://api.github.com/users/wroc), their"email"field isnull! How did GitHub link the email if the public profile states"email": null? - Why is
node_idencoded in Base64?
3. Why is node_id in Base64? (MDQ6VXNlcjExNDIwODIw)
If we decode the "node_id": "MDQ6VXNlcjExNDIwODIw" field in a Linux terminal:
echo "MDQ6VXNlcjExNDIwODIw" | base64 -d # Output: 04:User11420820 Why did GitHub engineers encode 04:User11420820 in Base64? It wasn't for encryption—it was a database architecture and API evolution decision driven by the GraphQL Relay Specification:
- In GitHub's relational database (MySQL), each table has its own sequential primary key (
id). There is anid = 11420820in theuserstable, but there can also be anid = 11420820in therepositoriesorissuestables. - When GitHub introduced its GraphQL API (v4), it needed a globally unique identifier (Global Node ID) so a generic
node(id: "...")query would know exactly which table toSELECTfrom. - Their initial solution combined the type length + entity name + primary key:
04:User11420820. - Why Base64? To create an Opaque Identifier (Opaque Token), discouraging clients from doing
split(":")in their code and allowing GitHub to change the underlying structure in the future without breaking API contracts.
And GitHub actually did change it! Compare the node_id from the 2015 wroc account (MDQ6VXNlcjExNDIwODIw — plain text in Base64) with the node_id from my newer lipebackend account (U_kgDOE_lvuA — serialized in binary MessagePack + Base64).
4. How Did GitHub Link the Account if "email": null in the Public API?
If you query [https://api.github.com/users/wroc](https://api.github.com/users/wroc) (or my own profile [https://api.github.com/users/lipebackend](https://api.github.com/users/lipebackend)), you will see:
{ "login": "wroc", "id": 11420820, "node_id": "MDQ6VXNlcjExNDIwODIw", "email": null, "created_at": "2015-03-11T08:40:54Z" } The "email": null field in the public API DTO only means the user chose not to display a public email address on their profile bio. However, under the hood, when a commit arrives via git push, GitHub's backend performs internal identity resolution:
- Legacy
@users.noreply.github.comRouting Rule: Accounts created before 2017 used the<username>@users.noreply.github.comformat (newer accounts use<id>+<username>@users.noreply.github.comspecifically to prevent collisions or broken links when changing@username). When GitHub parseswroc@users.noreply.github.comin the commit, it extracts thewroclogin and queries the users table directly (WHERE login = ?). - Internal Private Email Table (The "Identity Oracle"): Even if you don't use
@users.noreply.github.comand instead put someone's real personal email in the commit, GitHub's backend performs an internalJOINagainst its private registered emails table (user_emails)—even if that email is marked as private on their profile—and attaches the owner's public user object to the commit response!
Here is the complete flow happening behind the scenes:
[1. COMMIT TIME - 100% Offline on Local Machine] git commit writes plain text into .git/objects: author: "wroc <wroc@users.noreply.github.com>" (No password / No SSH key) | v [2. PUSH TIME - Authenticates Transport, NOT the Author!] git push connects using "lipebackend" SSH key GitHub server validates: "lipebackend owns the repo, push accepted!" | v [3. AUTOMATIC BACKEND JOIN ON GITHUB] GitHub parses commit text and runs a SELECT on its Internal User Database Matches the real "wroc" record (id: 11420820) without requiring a signature! | v [4. API RESPONSE / WEB UI] GET /repos/lipebackend/api-rest/commits/b1a5ca0 Returns JSON with real "wroc" account metadata and adds them to Contributors! 5. Proof of Concept (PoC): Testing in Practice (Anonymized Data)
To prove that any email registered on GitHub (even hidden with "email": null on the public profile) would be resolved and attached to my repository without any authentication from the other party, I ran a controlled test with a fellow developer's permission (anonymized below as dev-example / contact@example.dev).
First, we verify that their email is hidden on their public profile ([https://api.github.com/users/dev-example](https://api.github.com/users/dev-example)):
curl -s https://api.github.com/users/dev-example | grep -E '"(login|id|node_id|email)"' "login": "dev-example", "id": 9876543, "node_id": "MDQ6VXNlcjk4NzY1NDM=", "email": null, Next, we create an empty commit (--allow-empty) in our repository by overriding Git environment variables and pushing to origin:
GIT_AUTHOR_NAME="dev-example" \ GIT_AUTHOR_EMAIL="contact@example.dev" \ GIT_COMMITTER_NAME="dev-example" \ GIT_COMMITTER_EMAIL="contact@example.dev" \ git commit --allow-empty -m "chore: test commit author resolution" && git push origin HEAD We immediately query the newly created commit via GitHub's API:
curl -sL https://api.github.com/repos/lipebackend/api-rest/commits/<commit-sha> And GitHub's backend immediately responds with the real account linked:
{ "sha": "eaf17be95da2a3210efba894140287493da7b7a4", "commit": { "author": { "name": "dev-example", "email": "contact@example.dev", "date": "2026-10-17T02:26:52Z" }, "message": "chore: test commit author resolution", "verification": { "verified": false, "reason": "unsigned" } }, "author": { "login": "dev-example", "id": 9876543, "node_id": "MDQ6VXNlcjk4NzY1NDM=", "avatar_url": "https://avatars.githubusercontent.com/u/9876543?v=4", "url": "https://api.github.com/users/dev-example", "html_url": "https://github.com/dev-example", "type": "User" } } 6. Security Implications (AppSec, OSINT, and Bug Bounty)
While Git treats this as expected behavior (since Linus Torvalds designed Git as a decentralized system where maintainers apply emailed patches while preserving the original Author), the way GitHub resolves and links user accounts without enforcing cryptographic signatures by default opens up real-world attack vectors:
- Email-to-Account Enumeration Oracle (OSINT): Even if a user sets
"email": nullon their public GitHub profile, anyone who possesses an email address can create a dummy commit in a private repository, push it, and inspect the API response (or Web UI) to unmask the exact GitHub account (login,id,avatar_url) tied to that private email. - Commit & Contributor Spoofing: Malicious repositories frequently inject commits using the email addresses of high-profile developers into their main branch so GitHub displays their official avatars and profiles under the Contributors tab, manufacturing false credibility for supply-chain or social engineering attacks.
- Third-Party Integration Traps (Where Real Bug Bounties Live): GitHub itself documents this behavior as Known Issue / By Design because it exposes the
"verification": { "verified": false, "reason": "unsigned" }block. However, numerous third-party CI/CD tools, deployment bots, and enterprise integrations consume GitHub's Commits API and blindly trustresponse.author.login(orresponse.author.id), assuming GitHub has already authenticated the author's identity—completely forgetting to check whethercommit.verification.verified === true!
7. How to Protect Yourself
As a software engineer and architect, there are three essential layers of defense:
- Cryptographically sign all your commits (SSH or GPG Signing): Configure your SSH or GPG key in Git (
git config --global commit.gpgsign true) so all your legitimate commits return"verified": trueand display the green Verified badge on GitHub. - Enable Vigilant Mode on GitHub: Go to Settings → SSH and GPG keys → Vigilant mode and check "Flag unsigned commits as unverified". Any commit spoofing your email without your cryptographic signature will explicitly display an Unverified warning badge.
- If you build integrations using GitHub's API: Never trust a commit's
author.loginorauthor.idfields for authorization or security decisions without strictly validating thatcommit.verification.verified === truefirst.