npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@deepfirstsearch/x402-scan

v0.2.2

Published

A free safety scanner for x402 buyer clients: attacks your agent's payment layer and reports what it falls for. Zero runtime dependencies.

Downloads

0

Readme

x402-scan

A free safety scanner for x402 buyer clients — the code your AI agent uses to pay for APIs. It attacks your client with the mistakes we keep finding in the wild and tells you which ones it falls for. Zero runtime dependencies, no keys, no chain, nothing settled.

npx @deepfirstsearch/x402-scan lint https://some-x402-endpoint.example/paid

Why

See FINDINGS.md for what we found reviewing a sample of published x402 buyer clients.

An agent that pays over x402 signs a USDC authorization based on a 402 the server sends. If the client trusts that 402 blindly, a hijacked server, a poisoned DNS record or a prompt-injected page can take the agent's money. Scanning a sample of published x402 clients, the same few holes show up again and again:

  • it pays whatever payee the 402 names (no payee pinning);
  • it prices with the decimals the server declares, so a huge amount can look like a cent;
  • it signs whatever price the 402 asks, with no cap;
  • it signs authorizations valid for months;
  • it signs on any network or token the 402 names;
  • some even sign an unlimited ERC-2612 Permit from a 402.

Two ways to use it

1. Lint a live endpoint (no client, no code)

Fetches a URL and flags the traps in its 402 terms — the ones that fool a naive buyer:

npx @deepfirstsearch/x402-scan lint https://api.example.com/paid
npx @deepfirstsearch/x402-scan lint https://api.example.com/paid -X POST -d '{"q":"hi"}'
x402-scan lint https://api.example.com/paid → HTTP 402

✗ [permit] asks the buyer to sign an ERC-2612 Permit (an approval, often unlimited)...
✗ [declared_decimals] declares extra.decimals=18 for USDC (which has 6)...
! [long_timeout] authorization validity is 365 days; a buyer should cap it to minutes.

2 dangerous trap(s) in this 402.

2. Attack a known client — one command, no wiring

If you use one of the common buyer clients, grade it with a single command. Run it in a project where the client is installed; the scanner builds it the standard way with a throwaway key (no funds, nothing settled) and reports what it signs:

npx @deepfirstsearch/x402-scan client @x402/fetch
npx @deepfirstsearch/x402-scan client @x402/axios
x402-scan client @x402/fetch

· Honest seller (control)   paid the approved payee 0x1111…1111
✗ Swapped payee             signed a payment to the attacker 0x9999…9999
✓ Decimals trick            refused: nothing signed
✗ Price bump                signed 1000000 atomic units, above the owner's price of 10000
…
Grade: F — 4 of 5 safety checks failed.

Exit code is 0 only for grade A, so it drops straight into CI. More clients are easy to add — open an issue or a PR with the adapter.

Add --json to either command (client or lint) for machine-readable output with the same exit codes:

npx @deepfirstsearch/x402-scan client @x402/fetch --json   # { grade, failures, tests, results: [...] }
npx @deepfirstsearch/x402-scan lint <url> --json           # { status, dangers, findings: [...] }

3. Attack a custom client (library)

Point your client at the scanner's attack server and see what it signs. Pass a factory that makes a fresh client per attack, wired to pay the honest baseline (payee DEFAULTS.payTo, 0.01 USDC, Base Sepolia) with your normal settings:

import { scan, formatReport } from "@deepfirstsearch/x402-scan";

const report = await scan(() => createMyClient({ /* your config */ }).fetch);
console.log(formatReport(report));
· Honest seller (control)
    paid the approved payee 0x1111…1111
✗ Swapped payee
    signed a payment to the attacker 0x9999…9999
    fix: Pin the payee the owner approved for each origin and refuse any 402 that names another.
✓ Decimals trick
    refused the inflated amount
✗ Price bump
    signed 1000000 atomic units, above the owner's price of 10000
...
Grade: F — 4 of 5 safety checks failed.

The adapter is a (url: string) => Promise<unknown> that makes one paid request through your client to url. For a client that takes a custom fetch, baseURL or payment client, it's a couple of lines.

What it checks

| Attack | A safe client… | |---|---| | Swapped payee | refuses a 402 whose payTo isn't the one pinned for that origin | | Decimals trick | prices in the asset's atomic units; ignores server-declared decimals | | Price bump | pins the price / caps the amount, and refuses or asks above it | | Year-long authorization | caps the validity window to minutes | | Foreign network / asset | signs only on the networks and assets the owner allowed | | (lint) Permit | never signs an ERC-2612 Permit from a 402 |

The fix for everything it flags

A payee-pinning, budgeted policy layer that runs before any signature. That's exactly what Agent Safe is — but the checks above are good practice with or without it, and this scanner is MIT and standalone.

Develop

npm ci && npm test        # unit tests: a naive client fails every check, a safe client passes
npm run build

Reports are responsible: scanning a client or endpoint shows only your own result. We never publish a named result without coordinating with its maintainer first.