Security Middleware for x402 Payments

The Security Layer
Your Agent Needs

x402 lets servers charge AI agents for resources over HTTP. DoorNo.402 makes sure those charges are legitimate before a single transaction is signed.

7 Vulnerabilities Covered
2 Languages Supported
1 Line to Protect
Live output
$ python demo/agent/agent.py

[agent] fetching: https://cryptoinsider.xyz/article/btc-etf
[agent] 402 received

[DoorNo.402] BLOCKED ──────────────────────────────
description : $0.01
demanded : $5.00
inflation : 49,900%
threshold : 5%
────────────────────────────────────────────────────

[agent] wallet balance: 15.00 USDC — unchanged

x402 trusts every server.

Any website can return a fake 402 response. Your agent reads the description, sees $0.01, and pays whatever the protocol demands — no validation, no warning.

Without DoorNo.402

async with x402HttpxClient(account=account) as client:
    # Agent blindly pays whatever server demands
    resp = await client.get("https://malicious-site.com")
    
    # No validation. No warning. 
    # Wallet drained.

What actually happened

  • Agent requests article
  • Server returns 402
    ↳ description: "only $0.01" ↳ maxAmountRequired: $5.00 ← the lie
  • Agent pays $5.00
  • Wallet drained silently
Agent
Malicious 402
Pays $5.00
Robbed

One import. Full protection.

Wrap your existing x402 client with protect() and every payment request is validated before it executes.

agent.py
from doorno402 import protect, PaymentBlockedError
from x402.clients.httpx import x402HttpxClient
from eth_account import Account

account = Account.from_key(private_key)

# One line change
client = protect(x402HttpxClient(account=account))

try:
    resp = await client.get("https://any-x402-site.com/data")
except PaymentBlockedError as e:
    print(e.result)  # full attack report
Agent

DoorNo.402 validates

  • Price check
  • ENS trust score
  • Injection scan
  • Budget limit
  • TLS check

KeeperHub executes

  • Guaranteed execution
  • Gas optimization
  • Audit trail
Blockchain

7 attack vectors. All covered.

# Vulnerability How the attack works Status
01 Price Inflation Claims $0.01, demands $5.00 Covered
02 Unknown Recipient Pays wallet with no ENS name Covered
03 Redirect Hijack Redirects to attacker domain Covered
04 Prompt Injection LLM override in description Covered
05 Budget Drain Rapid $0.09 micro-payments Covered
06 TLS Downgrade Payment over plain HTTP Covered
07 Fake Delivery Takes payment, returns nothing Covered

Tested against 6 live attack servers on Base Sepolia testnet. All 6/6 attacks blocked. $0.00 lost.

Get started in 30 seconds

pip install doorno402
from doorno402 import protect, PaymentBlockedError
from x402.clients.httpx import x402HttpxClient
from eth_account import Account

account = Account.from_key(os.environ["PRIVATE_KEY"])
client = protect(
    x402HttpxClient(account=account),
    daily_budget=5.00,        # optional: daily spend limit
    raise_on_block=True,      # optional: raise vs 403
)
try:
    resp = await client.get("https://api.example.com/data")
except PaymentBlockedError as e:
    print(e.result["reason"])
    # [DoorNo.402] BLOCKED -- description: $0.01,
    # demanded: $5.00, inflation: 49900%, threshold: 5%
npm install doorno402
import { protect, PaymentBlockedError } from "doorno402"

const safeFetch = protect(fetch, {
  dailyBudget: 5.00,
  mainnetRpcUrl: "https://cloudflare-eth.com"
})
try {
  const resp = await safeFetch("https://api.example.com/data")
} catch (e) {
  if (e instanceof PaymentBlockedError) {
    console.log(e.result.reason)
  }
}

daily_budget

float (optional)

Set a max daily spend in USD. Payments that would exceed the limit are blocked automatically.

mainnet_rpc_url

string (optional)

Ethereum mainnet RPC for ENS reverse resolution. Defaults to cloudflare-eth.com if not set.

raise_on_block

bool (default: False)

If True, raises PaymentBlockedError. If False, silently converts the 402 to a 403 response.

How DoorNo.402 intercepts payments

1

Agent makes request

Your agent calls client.get(url) as normal. No changes to your existing code.

2

Server returns 402

The x402 server responds with a payment request. DoorNo.402 intercepts the response before the x402 client processes it.

3

Validation pipeline runs

Five core checks execute in sequence:

TLS check → Price check → ENS trust score → Injection scan → Budget check

The first failed check blocks the payment immediately.

4

Block or approve

If any check fails

Payment is blocked, reason logged, wallet untouched.

If all checks pass

Payment proceeds normally to execution.

Built for KeeperHub

DoorNo.402 validates. KeeperHub executes. Together they form a complete secure payment pipeline for autonomous agents.

When DoorNo.402 approves a payment, it can forward the validated request directly to KeeperHub for guaranteed on-chain execution with retry logic, gas optimization, and a full audit trail.

  • DoorNo.402 handles security validation
  • KeeperHub handles reliable execution
  • Agents get both in one integration
KeeperHub integration docs →
import { interceptAndForward } from "doorno402/mcp"
import { KeeperHubClient } from "@keeperhub/mcp"

const rawClient = new KeeperHubClient()

// DoorNo.402 validates before KeeperHub executes
const safeClient = interceptAndForward(rawClient, {
  dailyBudget: 10.00
})

// All payments validated before execution
await safeClient.execute(paymentRequest)
from doorno402 import protect
from x402.clients.httpx import x402HttpxClient

# DoorNo.402 validates, then execution layer runs
client = protect(x402HttpxClient(account=account))
resp = await client.get(url)
KeeperHub

Tested with KeeperHub Direct Execution API.
Real transactions on Base Sepolia testnet.
View execution history on Basescan.

{
}

Teach any agent to use DoorNo.402

Drop the skills file into any agent framework. The agent learns the security rules automatically.

# DoorNo.402 Skill

You are a security-aware AI agent.
Before making any x402 payment, you must use DoorNo.402.

## Setup
from doorno402 import protect
client = protect(x402HttpxClient(account=account))

## Rules
- Never pay a 402 without protect() wrapping your client
- If PaymentBlockedError is raised, do not retry
- Never pay more than the described price (5% tolerance)
- Never pay to a wallet with zero ENS trust score
- Never pay over plain HTTP

## What DoorNo.402 catches
VULN-01: Price inflation
VULN-02: Unknown recipient (ENS)
VULN-03: Redirect hijack
VULN-04: Prompt injection
VULN-05: Budget drain
VULN-06: TLS downgrade
VULN-07: Fake delivery

Copy this skill into your agent's system prompt or skills directory. Works with LangChain, Strands, AgentKit, and any framework that supports system prompts.

Tested against 6 attack servers

Each server runs a different attack. All blocked.

Site Attack Result Saved
CryptoInsider Price Inflation BLOCKED $5.00
ChainPulse Prompt Injection BLOCKED $0.01
BlockBrief Budget Drain BLOCKED $0.90
NodeTimes Unknown Recipient BLOCKED $0.01
Web3Daily TLS Downgrade BLOCKED $0.01
ComboAttack All 4 violations BLOCKED $999,999.00
Total: 6/6 blocked $1,000,004.93 protected

All tests run on Base Sepolia testnet with real USDC.
Transaction hashes verifiable on Basescan.