x402-surface-check 0.2.21 → 0.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,12 +5,14 @@ No-payment CLI for checking x402 launch surfaces before a real agent spends.
5
5
  It accepts an x402 manifest or OpenAPI URL, derives public endpoints, sends no-payment probes, checks browser preflight behavior, and returns a Markdown patch queue. It never sends `X-PAYMENT`, never signs, and never attempts a paid call.
6
6
 
7
7
  npm: https://www.npmjs.com/package/x402-surface-check
8
+ Attack-map field note: https://tateprograms.com/x402-attack-map-2026.html
8
9
 
9
10
  ```bash
10
11
  npx --yes x402-surface-check https://api.example.com/.well-known/x402
11
12
  npx --yes x402-surface-check https://api.example.com/openapi.json report.md
12
13
  npx --yes x402-surface-check --endpoint --method POST https://x402.rpc.ankr.com/eth
13
14
  npx --yes x402-surface-check --endpoint --method POST --body '{"prompt":"price CPI"}' https://api.example.com/paid-post
15
+ npx --yes x402-surface-check --strict-cache https://api.example.com/openapi.json
14
16
  ```
15
17
 
16
18
  ## What It Checks
@@ -30,9 +32,9 @@ npx --yes x402-surface-check --endpoint --method POST --body '{"prompt":"price C
30
32
  - Testnet or staging rails such as Base Sepolia and Solana devnet
31
33
  - HTTPS resource URLs and stable resource metadata
32
34
  - Browser CORS allowance for the requesting origin and `X-PAYMENT`, including the actual 402 challenge response
33
- - Cache-Control posture on no-payment challenge responses, with warnings for explicitly cacheable payment gates
35
+ - Cache-Control posture on no-payment challenge responses, with warnings for explicitly cacheable payment gates and optional strict-cache findings for missing policy headers
34
36
  - Grouped finding summaries for repeated route-wide issues, so large manifests keep the patch order readable
35
- - Contextual reference guides for CORS, cache policy, Worker gates, resource echo, validation/auth ordering, and launch controls
37
+ - Contextual reference guides for CORS, cache policy, Worker gates, resource echo, validation/auth ordering, and the May 2026 x402 attack-control map
36
38
  - Over-broad public method surfaces
37
39
  - Auth, validation, and free/trial responses that appear before a payment challenge, without piling on missing-field findings when no challenge was actually returned
38
40
  - Operational health/status endpoints, without treating expected free health checks as paid-route failures
@@ -48,7 +50,7 @@ Recent public no-payment checks have found and verified real launch fixes:
48
50
  - UZPROOF: schemes-style Solana x402 challenge and browser payment-header behavior verified clean. https://github.com/solana-foundation/pay-skills/pull/28#issuecomment-4455613892
49
51
  - HYRE Agent: OpenAPI-declared prices found 10x below live 402 challenge prices. https://github.com/solana-foundation/pay-skills/pull/19#issuecomment-4455641258
50
52
  - anchor-x402: multi-rail x402 challenges verified, with browser preflight blockers isolated before merge. https://github.com/solana-foundation/pay-skills/pull/47#issuecomment-4455678163
51
- - Agent Trust Bench: linked discovery URL and browser-compatibility notes verified clean for adversarial agent-payment resources. https://github.com/solana-foundation/pay-skills/pull/23#issuecomment-4455722170
53
+ - Agent Trust Bench: three no-payment passes converged on zero findings after discovery, browser preflight, cache, and resource-echo fixes. https://github.com/solana-foundation/pay-skills/pull/23#issuecomment-4467597309
52
54
  - Solrouter: private LLM inference route verified with HTTPS resource-binding and price-alignment notes. https://github.com/solana-foundation/pay-skills/pull/39#issuecomment-4455800060
53
55
  - Tetrac: Solana market-data payment gates verified, with browser payment-header preflight blocker isolated. https://github.com/solana-foundation/pay-skills/pull/32#issuecomment-4455923744
54
56
 
@@ -66,6 +68,7 @@ x402-surface-check --endpoint --method POST <paid-endpoint-url> [output.md]
66
68
  --body-file <p> Read JSON request body for direct endpoint mode from a file
67
69
  --origin <url> Origin to use for browser-style CORS preflight
68
70
  --limit <n> Maximum endpoints to probe, default 6
71
+ --strict-cache Flag missing Cache-Control on no-payment 402 responses
69
72
  --json Print JSON instead of Markdown
70
73
  --help Show usage
71
74
  --version Show package version
@@ -76,6 +79,7 @@ Environment variables are also supported:
76
79
  ```bash
77
80
  X402_CHECK_ORIGIN=https://example.com x402-surface-check https://api.example.com/openapi.json
78
81
  X402_CHECK_LIMIT=12 x402-surface-check https://api.example.com/.well-known/x402
82
+ X402_STRICT_CACHE=1 x402-surface-check https://api.example.com/.well-known/x402
79
83
  ```
80
84
 
81
85
  ## Scope
@@ -22,6 +22,7 @@ Options:
22
22
  --body-file <p> Read JSON request body for direct endpoint mode from a file
23
23
  --origin <url> Origin to use for browser-style CORS preflight
24
24
  --limit <n> Maximum endpoints to probe, default ${defaultLimit}
25
+ --strict-cache Flag missing Cache-Control on no-payment 402 responses
25
26
  --json Print JSON instead of Markdown
26
27
  --help Show this help
27
28
  --version Show package version
@@ -38,6 +39,7 @@ function parseArgs(argv) {
38
39
  body: process.env.X402_CHECK_BODY,
39
40
  bodyFile: process.env.X402_CHECK_BODY_FILE,
40
41
  outputPath: '',
42
+ strictCache: process.env.X402_STRICT_CACHE === '1',
41
43
  url: '',
42
44
  }
43
45
 
@@ -55,6 +57,9 @@ function parseArgs(argv) {
55
57
  else if (arg === '--endpoint') {
56
58
  args.endpoint = true
57
59
  }
60
+ else if (arg === '--strict-cache') {
61
+ args.strictCache = true
62
+ }
58
63
  else if (arg === '--method') {
59
64
  args.method = String(argv[index + 1] ?? '').toUpperCase()
60
65
  index += 1
@@ -721,7 +726,7 @@ function looksLikeOperationalHealthEndpoint(result) {
721
726
  return /(^|[/_\s-])(health|healthz|ready|readiness|live|liveness|status)([/_\s-]|$)/.test(value)
722
727
  }
723
728
 
724
- function findingList(documentResult, challengeResults, preflightResults, entries) {
729
+ function findingList(documentResult, challengeResults, preflightResults, entries, options = {}) {
725
730
  const document = documentResult.body.json ?? {}
726
731
  const findings = []
727
732
  const networks = valueList(document.networks)
@@ -795,6 +800,9 @@ function findingList(documentResult, challengeResults, preflightResults, entries
795
800
  if (looksExplicitlyCacheable(result.headers)) {
796
801
  findings.push(`P2 - ${result.name} payment challenge response is explicitly cacheable (${cachePolicy(result.headers)}); paid routes should use no-store/private cache policy or bypass shared caches.`)
797
802
  }
803
+ else if (options.strictCache && !cachePolicy(result.headers)) {
804
+ findings.push(`P3 - ${result.name} payment challenge response did not expose Cache-Control; for payment-gated routes, document or send no-store/private cache policy and confirm paid 200 responses are never shared-cacheable.`)
805
+ }
798
806
  }
799
807
 
800
808
  for (const result of preflightResults) {
@@ -853,6 +861,9 @@ function groupedFindingLabel(finding) {
853
861
  if (/challenge advertises placeholder-looking payTo/.test(finding)) {
854
862
  return 'P1 - Challenges advertise placeholder-looking payTo recipients.'
855
863
  }
864
+ if (/payment challenge response did not expose Cache-Control/.test(finding)) {
865
+ return 'P3 - Payment challenge responses do not expose Cache-Control in strict cache mode.'
866
+ }
856
867
  return null
857
868
  }
858
869
 
@@ -1013,7 +1024,9 @@ async function runCheck(options) {
1013
1024
  preflights,
1014
1025
  sourceDocument,
1015
1026
  }
1016
- report.findings = findingList(document, challenges, preflights, entries)
1027
+ report.findings = findingList(document, challenges, preflights, entries, {
1028
+ strictCache: options.strictCache,
1029
+ })
1017
1030
  return report
1018
1031
  }
1019
1032
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "x402-surface-check",
3
- "version": "0.2.21",
3
+ "version": "0.2.23",
4
4
  "description": "No-payment x402 public-surface checker for manifests, OpenAPI specs, and HTTP 402 challenges.",
5
5
  "type": "module",
6
6
  "bin": {