A stale Flux source URL left my cluster open to repojacking
I changed my GitHub username and updated one reference to the old repository URL, but not the one Flux uses to sync the whole cluster. For two months, the cluster only kept working because GitHub redirects renamed accounts. Anyone who registered the old username could have pushed their own manifests and Flux would have applied them. Nobody did, and nothing was changed.
Impact
- Exposed: full control of the cluster, from 2026-07-26 to 2026-09-23.
- Actual impact: none. The old username was never registered by anyone else.
Timeline
- 2026-07-26: GitHub username changed. The URL in the khider.fr HelmRelease is updated, the Flux
GitRepositoryingotk-sync.yamlis not. - 2026-09-23, 00:08: the
GitRepositoryURL is pointed at the new repository. - 2026-10-02: Flux is re-bootstrapped against the new repository over SSH.
Root cause
When a GitHub account is renamed, requests to the old URL are redirected to the new one, but only until someone registers the old username. At that point the old URL belongs to them.
The flux-system GitRepository is the root of
everything Flux deploys. Its Kustomization has prune: true,
and Flux applies changes with cluster-admin rights. A public repository
with the same name, branch and path under the old username would have
been pulled within minutes. Its contents would have been applied, and
anything of mine not in it would have been deleted. The
secretRef on the source does not prevent this, since a
public repository clones without credentials.
What went wrong
- The rename was followed by a manual fix of the one reference I remembered, not a search of the repository for the old name.
- Flux trusted whatever the URL returned. Nothing tied the source to my account or my commits.
Follow-ups
- Point the Flux
GitRepositoryat the new repository. - Re-bootstrap Flux against the new repository with SSH authentication.