Leaked Access Tokens
An over-scoped, non-expiring personal access token leaks to a public gist, and an attacker uses it to clone private repositories and push as the developer. Revoke and rotate the token, then reissue a fine-grained, least-privilege, short-lived one.
What Is Leaked Access Tokens?
A personal access token is a credential that stands in for an entire account when it calls a platform's API or clones its repositories. When such a token is over-scoped and never expires, a single leak becomes a long-lived master key, and the caller's real identity or intent no longer matters, because whoever holds the token is treated as the developer who created it. This exercise puts you on both sides of exactly that failure. As Bob, an attacker who scrapes public gists, CI logs, and commits, you find a Loomwick developer's personal access token sitting in plain text, check its scope and see broad repository and organization-admin access with no expiry, present it in an Authorization header to list the organization's private repositories, and then clone a private repo and push a change back, all authenticated as the developer. As Alice, a security engineer at Loomwick, a marketing-automation company, you own the organization's tokens and the response when one leaks. A secret-scanning alert emails you that a token is exposed publicly, you confirm it is a classic broad-scope personal access token that far exceeds what the job needed and never expires, and you contain it: revoke the token immediately, then reissue a fine-grained replacement with least-privilege scope, access limited to a single repository, and a short expiry, and enable push protection and secret-scanning alerts before filing the report. This exercise is about token scope and lifecycle, which is distinct from protecting the secrets that live inside repository content; here the token itself is the credential, and its scope and expiry are the blast radius.
What You'll Learn in Leaked Access Tokens
- Recognize why an over-scoped, non-expiring personal access token is dangerous: a single leaked copy grants broad, long-lived access to clone private repositories and push, all as the developer
- Trace how an attacker turns a token scraped from a public gist into real access by presenting it in an Authorization header to list private repositories and then cloning and pushing
- Respond to a leak correctly by revoking and rotating the token rather than just deleting the public copy, since anyone who already copied it keeps access until the token is killed
- Reissue a fine-grained, least-privilege token scoped to a single repository with a short expiry, instead of a classic broad token that grants sweeping access with no expiry
- Reduce exposure by enabling secret scanning and push protection so tokens leaked to gists, CI logs, or commits are flagged and blocked early
Leaked Access Tokens — Training Steps
-
Bob's gist harvester
Bob does not read gists by hand. He runs a small scraper that pages the platform's public gist feed and scans every file for anything shaped like a credential. The feed is open to anyone, no account needed, so the whole stream of public gists is his to search.
-
Run the harvester
Bob runs the scraper. It pulls the public gist feed and matches each file against its credential patterns. Most hits are dead, expired or disabled keys, but one is live: a Loomwick personal access token sitting in a developer's deploy gist.
-
Open the flagged gist
Bob opens the gist the scraper flagged. The deploy helper is a gift: it carries the token in full, names the repository it targets, and shows exactly how it is used.
-
What the token can do
Before using it hard, Bob asks the platform what the token is. He calls Loomwick's API with the token in an Authorization header, and the response describes the credential itself. It belongs to an ordinary developer, not an admin, yet the scopes are sweeping and there is no expiry.
-
List the private repositories
Now Bob puts the token to work. He asks the API to list the organization's repositories, and the private ones come back alongside the public one. He has never held a Loomwick account. The token alone is enough.
-
Clone a private repo
With the token, Bob clones a private repository straight to his own machine. The gist handed him both the credential and the exact repository it targets. The clone pulls down billing-core in full: source, config, and history.
-
Open the webhook file
Read access is bad enough, but the token can write too. Bob opens a webhook file in the cloned repository, looking for a quiet place to add a line of his own.
-
Plant the change
Bob adds a single line. Every billing event the service forwards now goes to his own collector as well as the internal ledger. It is a small, quiet change, the kind that slips through a busy review.
-
Commit the change
Bob commits the edit. The message reads like a harmless forwarder tweak, but the diff quietly carries his exfiltration line.
-
Push as the developer
Then Bob pushes the commit back to Loomwick over the authenticated repository URL. The platform accepts it: the token is treated as Maya, so the write lands on the default branch. A leaked token is not just read access. It carries the developer's full identity, including the power to change what ships.