{"slug": "the-60-second-check-before-every-npm-install", "title": "The 60-Second Check Before Every npm install", "summary": "A developer published a six-step pre-install checklist for vetting unfamiliar npm and PyPI packages, built around registry queries such as `npm view` and the PyPI JSON API. The checklist covers exact spelling, maintainer and repository links, package age and publish history, weekly download counts, install scripts, and lockfile diffs. It cites typosquatting incidents including the 2017 Slovak National Security Office's ten fake Python packages and npm's 13 releases of a fake `crossenv` package, plus a 2025 USENIX Security study finding 19.7% of 2.23 million AI-generated code samples referenced nonexistent package names.", "body_md": "Honestly, I'd say `npm install` is the riskiest five seconds of your day now that typosqatting is so common. It's the potential moment a attacker's code gets a chance to run on your laptop or your CI runner.\n\nThis is not theoretical anymore. It has happened several time, at a huge scale! Some incide\n\nIn **2017, The Slovak National Security Office** flagged ten fake Python packages. One fake package was `urllib`,instead of `urllib3`.\n\nThey also collected the system's data! [news link](https://news.sophos.com/en-us/2017/09/19/pypi-python-repository-hit-by-typosquatting-sneak-attack/)\n\n**npm's official record listed 13 releases of a fake package** called `crossenv` for the real pkg `cross-env`. Funfact if you today run `npm view crossenv`, it returns `0.0.2-security`. This is apparantly a placeholder npm put in its place.\n\n**19.7% AI generated code samples had package names that doesn't exist.** Yes, in 2025 USENIX Security study checked 2.23 million AI-generated code samples. If I were an atatcker, I'd register those names and wait. This is called [slopsquatting.](https://labs.cloudsecurityalliance.org/research/csa-research-note-slopsquatting-ai-supply-chain-20260419/)\n\nAfter reading about these attacks, I'd the first thing is to have my own investigation. Here are my findings. Enjoy the blog further:\n\nThis is for developers, SREs, DevOps engineers, and the people who review their pull requests. Run these before you add a package you have not used before:\n\n**1. Exact spelling and ecosystem**\n\nRead the name letter by letter against the project's own docs. Then ask the registry if it exists.\n\n```\nnpm view cross-env name version\npython3 -m pip index versions requests\n```\n\n**A missing name returns `E404` on npm, or `No matching distribution found` on pip. **\n\n**2. Publisher and repo link**\n\nCheck who owns the package. Then check where it says its code lives.\n\n```\nnpm view cross-env maintainers repository.url\n# maintainers = 'kentcdodds <me@kentcdodds.com>'\n# repository.url = 'git+https://github.com/kentcdodds/cross-env.git'\n\ncurl -s https://pypi.org/pypi/requests/json | python3 -c \"import sys,json; i=json.load(sys.stdin)['info']; print(i['version'], i['project_urls'])\"\n```\n\n** 3. The Package age and publish history **\n\nYou can use this to check about the package's record-\n\n```\nnpm view cross-env time.created time.modified\n# time.created = '2015-10-01T23:19:27.453Z'\n\nnpm view cross-env time\n\ncurl -s https://pypi.org/pypi/requests/json | python3 -c \"import sys,json; r=json.load(sys.stdin)['releases']; print(min(f['upload_time_iso_8601'] for v in r.values() for f in v))\"\n```\n\nThe red flags would be spotted if: (a) it's been created recently, but has a famous name (b)there's a new maintainer on an old package.\n\n**4. Weekly downloads vs. the real project**\n\nAnother interesting thing that you can do while patrolling is to compare the lookalike with the project it resembles.\n\n```\ncurl -s https://api.npmjs.org/downloads/point/last-week/cross-env\ncurl -s https://pypistats.org/api/packages/requests/recent\n```\n\nLow count, new package => normal. \n\nLow count, fake package for a famous name => suspicious.\n\nFor your example: `pypistats` excludes known mirrors and updates once a day. (Ref: [PyPI Stats API](https://pypistats.org/api/))\n\n**5. Install scripts**\n\nHere's my observation. Many legitimate packages have a script. I understood this from the hidden install scripts are [how the September 2025 Shai-Hulud worm ran its code](https://snyk.io/blog/sha1-hulud-npm-supply-chain-incident/).\n\n```\nnpm view esbuild scripts.postinstall\n# node install.js\n```\n\n**6. Lockfile diff**\n\nOne new dependency can pull in many. As a developer, you must never skip reading what changed.\n\n```\ngit diff origin/main -- package-lock.json\n\n# only new install scripts\ngit diff origin/main -- package-lock.json | grep -E '^\\+.*\"hasInstallScript\"'\n\n# for a version bump, see what changed in the code\nnpm diff --diff=pkg@1.0.0 --diff=pkg@1.0.1 --diff-name-only\n```\n\nLook for names you did not expect, and any added \"hasInstallScript\": true. For Python, do the same with git diff requirements.txt. [npm diff docs](https://docs.npmjs.com/cli/v11/commands/npm-diff)\n\nThey're merely the checks, but do not really make any install \"safe\". These are the following limitations:\n\n• A real package published by a real maintainer whose account was compromised will pass all six checks.\n\n• A lockfile poisoned before anyone noticed will look normal in a diff.\n\n• Malicious code that lives in a package's runtime JavaScript, not in an install script, is not stopped by ignore-scripts.\n\nI came across this blog- [What Is Typosquatting? Attacks, Examples, and AI Risks.](https://www.cleanstart.com/blogs/what-is-typosquatting-attacks-examples-and-ai-risks) by CleanStart.\n\nIn this, you can checkout the for the org-level version of this checklist.\n\nIt's also my first blog here. Please share your love in comments!❤️", "url": "https://wpnews.pro/news/the-60-second-check-before-every-npm-install", "canonical_source": "https://dev.to/trivedi-khushi/the-60-second-check-before-every-npm-install-2bg", "published_at": "2026-10-19 15:32:41+00:00", "updated_at": "2026-10-19 15:44:47.793029+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools"], "entities": ["npm", "PyPI", "Slovak National Security Office", "USENIX Security", "crossenv", "cross-env", "Shai-Hulud"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/the-60-second-check-before-every-npm-install", "markdown": "https://wpnews.pro/news/the-60-second-check-before-every-npm-install.md", "text": "https://wpnews.pro/news/the-60-second-check-before-every-npm-install.txt", "jsonld": "https://wpnews.pro/news/the-60-second-check-before-every-npm-install.jsonld"}}