Skip to main content

Verify a package is real before you install it — built for the AI-coding era of typosquatting and slopsquatting.

Project description

wary

Verify a package is real — and isn't a typosquat — before you install it.

$ wary check requsts --ecosystem pypi
  💀 requsts [pypi] — nonexistent
      → 'requsts' does not exist on pypi. If an AI assistant suggested this
        package, it's a hallucinated name — do not install it.

  1 packages checked — 0 ok, 0 suspicious, 0 likely squats, 1 nonexistent
  RESULT: FAIL

Why this exists

AI coding assistants are extremely good at writing code and occasionally hallucinate a package name that sounds exactly right and doesn't exist. Security researchers call this slopsquatting: attackers watch for these hallucinated names — Copilot, ChatGPT, and Claude all tend to hallucinate the same plausible-sounding names repeatedly — and register them first, so the next developer who blindly installs what their AI suggested gets malware instead.

This isn't hypothetical. 2026 alone has seen a steady drumbeat of real supply-chain compromises: the Axios npm hijack (100M+ weekly downloads, North Korea-attributed), the LiteLLM PyPI poisoning, a compromised Red Hat npm namespace, a fake @bitwarden/cli impersonating the real Bitwarden CLI, and typosquatted OpenSearch/DevOps packages harvesting AWS and CI/CD credentials. Every one of these relied on the same thing: a developer (or a CI pipeline) installing a name that looked right.

Excellent general supply-chain-security tools exist (Socket.dev, Snyk) — but they're built and priced for teams of 5+ developers. wary is narrower and free at the individual level: is this specific name I'm about to install real, and does it look like it's impersonating something popular.

Install

pip install wary

Use it the moment it matters

Right after your AI assistant suggests a package, before you run the install:

wary check some-package-suggested-by-copilot --ecosystem npm

Scan a whole project

cd your-project
wary scan

Check only what's new (the CI use case)

wary diff /path/to/base-branch-checkout /path/to/pr-branch-checkout

This is what the GitHub Action runs on every PR — see action/README.md. It only flags dependencies that are new in the diff, so it's quiet on unrelated PRs and loud exactly when something new shows up.

What it checks

For every package name:

  1. Does it exist at all? If not, and this came from an AI suggestion, it's a hallucination — the single most actionable finding wary produces.
  2. Is the name a squat pattern against one of ~650 popular npm/PyPI packages — character swaps, keyboard-adjacent typos, combosquats (lodash-utils), delimiter swaps (react_dom), pluralization, vowel swaps?
  3. Is it young enough to be an active impersonation rather than a coincidentally similar independent package?
  4. Does its publish history look automated — a burst of many versions in a very short window?

See docs/DETECTION.md for the full pattern taxonomy and the verdict logic.

Limitations (read this)

  • This is a fast, automated first pass, not a guarantee. A package that passes every check here can still be malicious in ways that don't show up in name similarity or publish timing (a legitimately-named package whose maintainer's account gets compromised, for instance — exactly what happened to Axios).
  • The protected-name list (src/wary/popular_names.py) is a curated, versioned snapshot of ~650 packages, not a live top-N-by-downloads query — see the file for why.
  • Currently covers npm and PyPI. See docs/ROADMAP.md for what's next.

Development

pip install -e ".[dev]"
pytest                    # unit tests (fast, offline)
pytest -m integration     # + live tests against real npm/PyPI registries

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wary_sh-0.1.0.tar.gz (37.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wary_sh-0.1.0-py3-none-any.whl (18.3 kB view details)

Uploaded Python 3

File details

Details for the file wary_sh-0.1.0.tar.gz.

File metadata

  • Download URL: wary_sh-0.1.0.tar.gz
  • Upload date:
  • Size: 37.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.9

File hashes

Hashes for wary_sh-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2835a2b7904174a8f117e66630de5448f3ec482b0558eb2ea1f20da7c340221e
MD5 b4658da8335a5691b54b4498ea7795d0
BLAKE2b-256 73d469cfdbc7f5af9afc6f47e073c1d10392d4d084335f10c724d47359e82ccf

See more details on using hashes here.

File details

Details for the file wary_sh-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: wary_sh-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 18.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.9

File hashes

Hashes for wary_sh-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3969d26ace43797be0da5ae71e91f604f2f1396ea8c064b158c6ba09d3ee5b0c
MD5 22616a78e910a03d6140d7f2b308b2f7
BLAKE2b-256 7a0bfa5ad8294302cf2d6bf09c0914389f478cd8cdb99999e12d439e21306f3c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page