x402 lets servers charge AI agents for resources over HTTP. DoorNo.402 makes sure those charges are legitimate before a single transaction is signed.
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.
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.
Wrap your existing x402 client with protect() and every payment request is validated before it executes.
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
| # | 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.
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)
}
}
Set a max daily spend in USD. Payments that would exceed the limit are blocked automatically.
Ethereum mainnet RPC for ENS reverse resolution. Defaults to cloudflare-eth.com if not set.
If True, raises PaymentBlockedError. If False, silently converts the 402 to a 403 response.
Your agent calls client.get(url) as normal. No changes to your existing code.
The x402 server responds with a payment request. DoorNo.402 intercepts the response before the x402 client processes it.
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.
Payment is blocked, reason logged, wallet untouched.
Payment proceeds normally to execution.
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.
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)
Tested with KeeperHub Direct Execution API.
Real transactions on Base Sepolia testnet.
View execution history on Basescan.
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.
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.