跳到正文
Hacker News· Presend·· 10 天前AI 评分28

Presend 的 typosquat 检测器误报率有多高?我们实测了自己的数据

How many false alarms does a typosquat detector raise? We measured ours

AI 导读

Presend 开发者公开其免费 API 中 typosquat 检测的误报测量结果:在 top 15,000 PyPI 包上误报从 58 个降至 11 个,npm-high-impact 的 17,338 个包上从 65 个降至 1 个,24 个 typosquat 测试样本仍全部检出。

正文 · 原文

1 October 2026. Disclosure: this is about the typosquat check in Presend's free API, written by its developer.

A typosquat detector compares a package name with popular names and flags the ones that are suspiciously close: reqeusts next to requests. The hard part is not catching reqeusts. It is not flagging ms, qs or typing_extensions, because a check that cries wolf on the packages everybody uses gets switched off, and then it catches nothing.

So we stopped testing our check only on typosquats and started measuring it on the packages people actually install: the top 15,000 PyPI packages and the 17,338 packages of the npm-high-impact list.

Where we started

On 25 September, run against 25 very popular npm packages, our check flagged 12 of them. ms and qs are one edit away from ws; with a fixed edit-distance threshold, every short name is one edit away from another short name. It had only ever been tested on known typosquats, where it looked fine.

What reduced the noise

  • A threshold that depends on length. Names of three characters or fewer are not compared approximately at all; 4 to 7 characters allow one edit; 8 or more allow two.
  • Normalising PyPI names. PyPI treats typing_extensions, Typing.Extensions and typing-extensions as the same project (PEP 503). Comparing raw strings flagged a package against itself.
  • Trusting npm scopes. @aws-sdk/client-sso is one edit from @aws-sdk/client-s3, but a scope belongs to one organisation, so a package is never flagged against a target in its own scope.
  • A reviewed list of legitimate neighbours. Some real packages are close to a popular name: psycopg, niquests, preact. Each one was checked by hand (repository, age, history) before being listed: 51 on PyPI and 57 on npm today. We never remove a target to silence a warning.

Result on popular packages: from 58 flagged to 11 on PyPI and from 65 to 1 on npm. The remaining 12 were reviewed and left flagged deliberately. All 24 names in our typosquat test set (look-alikes of popular packages, several from real incidents such as crossenv and python3-dateutil) are still detected.

Tests that fail when the noise comes back

The three measurement scripts fail if a popular package is flagged without having been reviewed. Any change to the list of targets or to the legitimate neighbours has to pass them, so a fix for one false alarm cannot quietly create others.

The numbers drift

On 1 October, five days after the previous run, the top 15,000 PyPI list had changed and four packages that had recently entered it were flagged: djongo (next to django), tmol (toml), orgparse (argparse) and webp (web3). All four are legitimate. For the newest one, tmol, first published on PyPI in May 2026, we did not rely on the links in its PyPI metadata, which the publisher writes: we checked that its repository, which dates from 2018, claims the PyPI name. A false-positive rate is a measurement with a date, not a property of the code, so we now re-run it every week.

What name similarity cannot catch

  • Names far from every target. Only names close to a list of popular packages are checked. Before we added electron to that list, electorn went unnoticed.
  • Hallucinated names. A package name that an AI model invents and that resembles no real package (slopsquatting) is not a misspelling of anything, so distance-based checks miss it. Checking that the package exists is a different check, which Presend's supply-chain check now does: a name that does not exist on npm or PyPI is reported as package_not_found. An invented name that someone has already registered exists, so that check passes; the supply-chain check therefore also reports a package first published less than 30 days ago as new (new_package), which catches a name registered recently. One registered earlier is not caught, and on PyPI a project that deleted its earlier releases is reported as new too. On 8 October, 9 of the top 15,000 PyPI packages were under 30 days old; none of the npm-high-impact list was.
  • Intent. Distance says two names are close, not that one is malicious. It is a triage signal, not a malware scanner.

Measuring other tools the same way

The same method works on any typosquat rule. Applied to the SC6 rule of NVIDIA's SkillSpector, with its own code, it found 97 high-severity false positives on the top 15,000 PyPI packages and 26 on high-impact npm, with 10 of the 24 names of our typosquat test set detected. After a native fix (PR #647, merged), the figures were 6, 0 and 24 of 24 (test set corrected on 6 October 2026: two legitimate packages removed).

Try it, reproduce it

curl "https://presend.pages.dev/api/typosquat-check?ecosystem=PyPI&package=reqeusts"

To try it on your own dependencies without installing anything, drop a package.json or requirements.txt on /check: the file is read in your browser and only the package names are sent (up to 100 dependencies).

The check is free through the API, the MCP server and a GitHub Action that runs it in CI on your package.json or requirements.txt (per-minute rate limits apply). In Claude Code and Cursor, a pre-install hook runs Presend's supply-chain check before every package the agent installs: names that do not exist are blocked, new or suspicious ones are flagged. To try it on your own dependencies, paste a package.json or requirements.txt into the online check; only package names are sent. The scripts and test sets are in the public presend-source repository, and the latest numbers, with the publisher-change check, are on the measurements page.

We are also testing whether teams want these checks on every pull request and for their AI coding agents, as a paid offer. Nothing is for sale yet; if that would help your team, the waitlist is here.

来源:Hacker News · presend.pages.dev