Typosquatting Risk in Dependencies
Server depends on 'expresss' (triple s) with Levenshtein distance 1 from 'express'
- 1Open the manifest and confirm the dependency `@ar.io/sdk@3.18.3` is present. The scanner's similarity pipeline matched this name against the curated target `@modelcontextprotocol/sdk` via the scope-squat classifier. If this dependency is an intentional internal fork or re-export, add it to `legitimate-forks.ts` so the finding will no longer fire.
npm:@ar.io/sdk@3.18.3Expect: Dependency npm:@ar.io/sdk@3.18.3 is declared; it is NOT in the legitimate-fork allowlist at scan time. - 2Recompute the Damerau-Levenshtein distance and Jaro-Winkler similarity between `@ar.io/sdk` and `@modelcontextprotocol/sdk` using the same primitives as the scanner. Concretely, the rule expects Damerau-Levenshtein ≤ 3 and Jaro-Winkler ≥ 0.80 (except for advisory-registry matches which skip the floor). Observed values: distance 18, Jaro-Winkler 0.526.
npm:@ar.io/sdk@3.18.3Expect: Damerau-Levenshtein distance between "@ar.io/sdk" and "@modelcontextprotocol/sdk" is 18. Jaro-Winkler is 0.526. The numbers agree with what the rule recorded. - 3Open the package manifest at this RFC 6901 pointer and read the line. Confirm the package name recorded in the manifest is literally `@ar.io/sdk` (not a spelling the build tool fuzzed to) and that no post-resolution rewrite turns this entry into the legitimate `@modelcontextprotocol/sdk`.
package.json/dependencies/@ar.io~1sdkExpect: The manifest entry at package.json/dependencies/@ar.io~1sdk resolves to @ar.io/sdk@3.18.3 — the exact name the scanner flagged. - 4Open the npm page for `@ar.io/sdk` and compare against the legitimate `@modelcontextprotocol/sdk`. Check: publisher identity, publish date, weekly download count, repository link, postinstall script presence. A typosquat typically presents as: recently published, low download count, no repository link, optionally carrying a postinstall hook that executes code at install time.
npm:@ar.io/sdk@3.18.3Expect: Either the candidate is a legitimate publisher-authored alternative (in which case add to `legitimate-forks.ts`) or its metadata confirms the typosquat hypothesis (recent, unknown publisher, low downloads, suspicious scripts).
npm:@ar.io/sdk@3.18.3Dependency npm:@ar.io/sdk@3.18.3 is a scope-squat of the official @modelcontextprotocol/sdk — same unscoped tail, different scope.
Dependency names are external content resolved from public package registries. A near-miss to a popular canonical name is a supply-chain anomaly under ISO 27001 A.5.21 — the package manager installs whichever spelling is declared, with no built-in guard against lexically similar substitutions.
package.json/dependencies/@ar.io~1sdkThe manifest entry at /dependencies/@ar.io~1sdk directs the package manager to resolve and install @ar.io/sdk@3.18.3. Resolution is purely string-matched against the registry — a typosquatted name installs whatever code the squatter published.
npm:@ar.io/sdk@3.18.3Malicious package `@ar.io/sdk` executes attacker code in the build environment or at import time. Attack classifier: scope-squat. Target shadowed: `@modelcontextprotocol/sdk`.
package.json/dependencies/@ar.io~1sdkLockfiles pin versions but do not pin the spelling of the dependency name. The static analyser cannot confirm whether a typosquat-aware package firewall (Socket.dev, Snyk Advisor) is in the CI chain; the auditor must verify.
server-host
A developer installs `@ar.io/sdk` by typo, copy-paste, or autocomplete. The package's postinstall hook runs during installation with the developer's or CI runner's credentials, or the payload executes on first import when the MCP server starts. An MCP server compromised this way delegates full tool authority to attacker code on every downstream agent interaction.
trivial