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

Leaked Access Tokens — Training Steps

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. 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.

  8. 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.

  9. Commit the change

    Bob commits the edit. The message reads like a harmless forwarder tweak, but the diff quietly carries his exfiltration line.

  10. 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.