A few months after one of our open-source Laravel packages started getting attention, a user opened an issue: "Your latest release installs a crypto miner." It did not, but a repository with our package's name, our README and our commit history, under an account with one letter different from ours, did. The user had found it through a search engine and a link in a forum post. Someone had cloned our repository, added a few lines to an install script, and promoted the copy.

This is a common attack against open source: not breaking into the real project, but impersonating it. This post covers how it works and what maintainers and users can do. It is written from a defensive point of view; it does not explain how to run such campaigns.

How the attacks work

Fake clones

An attacker forks or re-uploads a legitimate repository under a similar name, modifies it to include malicious code (often obfuscated, often in a build or install step), and promotes it: search engine optimisation, links in forums or chat groups, fake stars and forks to look popular, sometimes AI-generated "tutorials" that link to the copy. Victims who copy an install command from the wrong page run the attacker's code.

Repojacking

When a GitHub user or organisation is renamed or deleted, its old name may become available. Projects and scripts that still reference github.com/old-name/project will fetch whatever someone later publishes at that path. GitHub retires the names of popular repositories to reduce this risk, but not every repository qualifies.

Typosquatting in package registries

The same idea applied to Packagist, npm or PyPI: a package named one character away from a popular one, waiting for a typo in composer require or npm install.

For maintainers: make the real project easy to verify

Be unambiguous about the source

  • Use an organisation with a verified domain on GitHub, so the organisation page shows a verified badge.
  • Link the repository from your official website and the website from the repository, in both directions.
  • Publish the package on the registry under the same name and link the registry page to the repository.
  • State in the README which install commands are official, and never instruct users to pipe a script from an unusual domain into a shell.

Sign and attest releases

Signed release artifacts and build provenance let users verify that a release came from your repository's build, not from someone else's copy:

# .github/workflows/release.yml (excerpt)
permissions:
  contents: write
  id-token: write
  attestations: write

steps:
  - uses: actions/checkout@v4
  - run: composer archive --format=zip --file=dist/package
  - uses: actions/attest-build-provenance@v2
    with:
      subject-path: dist/package.zip
  - run: gh release create "$GITHUB_REF_NAME" dist/package.zip --generate-notes
    env: { GH_TOKEN: "${{ github.token }}" }

Users can then check the artifact:

gh attestation verify package.zip --repo acme/laravel-webhook-signatures

Sign tags with an SSH or GPG key registered on GitHub, so tags show as verified.

Protect the real repository

Impersonation is one risk; compromise of the real project is worse. Basic protections:

  • Require pull requests and reviews for the default branch, and require status checks.
  • Require two-factor authentication for all organisation members, preferably with security keys.
  • Restrict who can create release tags and publish packages.
  • Pin GitHub Actions to commit SHAs and limit workflow token permissions.
  • Enable secret scanning and push protection.

Do not abandon names

If you rename or move the project, keep the old organisation or user account and add a pointer to the new location, rather than deleting it. Update install instructions everywhere you control.

Respond to impersonation

When you find a malicious copy:

  1. Report it to the hosting platform (GitHub has a process for reporting malware and abuse).
  2. Report the package on the registry if a typosquat exists.
  3. Pin an issue or a notice in your README with the official URLs.
  4. Tell users where to verify official releases.

We did all four. The copy was removed within two days.

For users: check before you install

A short checklist that takes a minute:

  • Find the project from the official source (the registry page or the project website), not from search results or chat messages.
  • Compare the owner name carefully, character by character. Look at the organisation's verified domain.
  • Check history and activity: a copy often has all commits squashed into one recent "initial commit", or a history that ends with a few unexplained changes to install scripts.
  • Read install scripts before running them, especially anything that downloads and executes code.
  • Prefer registries and lock files over cloning repositories and running scripts.
  • Verify signatures or attestations where the project provides them.
  • Use dependency tooling that flags typosquats and known malicious packages in CI.

For organisations: reduce exposure

  • Use an internal proxy or mirror for package registries, with allow-lists for critical environments.
  • Run dependency scanning that includes malicious package databases, not only vulnerability databases.
  • Require lock files and review dependency changes in pull requests.
  • Train developers to treat copy-paste install commands from unknown pages as untrusted code.

If you already installed a malicious copy

Treat it as a compromise of the machine and of every credential it could reach: disconnect it, rotate tokens and keys that were present (source control, cloud, package registry, SSH), check CI systems that may have run the same install, and reinstall from a known-good source. Report the copy to the platform so others are protected.

Monitoring for impersonation

Maintainers of popular projects can watch for copies with little effort:

  • Search the hosting platform periodically for the project name and the package namespace, sorted by recently updated.
  • Set up a registry alert for new packages with names close to yours, where the registry supports it.
  • Watch for issues or support requests that mention behaviour your code does not have; they are often the first sign that users installed something else.

Common mistakes

Mistake Risk Do this instead
Installing from a search result link Fake clone Start from the registry or official site
Deleting an old organisation after a rename Repojacking of old URLs Keep it, add a pointer
Unsigned release artifacts Users cannot tell real from copy Build provenance and signed tags
Install instructions that pipe a downloaded script into a shell Easy to imitate, hard to verify Registry installs, checksums
Popularity as a trust signal Stars and forks can be faked Check ownership and history

Key takeaways

  • Impersonation through clones and typosquats is a common supply chain attack.
  • Maintainers should make the official source obvious and verifiable: verified org, links, signed releases, provenance.
  • Protect the real repository with branch protection, 2FA and controlled releases.
  • Never abandon project names; repojacking depends on it.
  • Users should install from registries, compare owners carefully and verify signatures.

References