T09 · Insecure Skill Coding Practices
- Location
SKILL.md:297- Finding
Payment Verification Trusts HTTP Status Instead of Explicit Facilitator Validation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a non-executable payment-integration guide, but some payment-control examples are unsafe to copy into real services without review.
Install only if you will treat it as educational material, not production-ready payment code. Before using the examples with real money or protected content, align the environment variable names, remove unnecessary secrets, validate facilitator responses strictly, fail closed on verification problems, keep bundle balances server-side, and avoid putting real private keys in copied test code.
SKILL.md:297Payment Verification Trusts HTTP Status Instead of Explicit Facilitator Validation
SKILL.md:1516Client-Held Bundle Counter Allows Replay and Unlimited Paid Access
The skill metadata declares credentials named WALLET_ADDRESS and AGENT_SIGNING_KEY, but the code samples consistently read MERCHANT_WALLET_ADDRESS and do not actually consume AGENT_SIGNING_KEY. This mismatch can cause operators to misconfigure deployments, leading to broken payment enforcement or accidental use of the wrong secrets in production.
The guide assures readers that only public wallet addresses are needed and that no private keys are referenced, but later testing and buyer-agent examples require a payer private key or wallet-signing capability. This contradiction can mislead users about secret-handling requirements and cause unsafe key management practices when they discover private signing material is actually needed.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"scheme": "exact",
"network": "eip155:8453",
"maxAmountRequired": "1000000",
"resource": "https://api.example.com/data/premium",
"description": "Premium data feed access",
"mimeType": "application/json",
"payTo": "0xYourWalletAddress",
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"scheme": "exact",
"network": "eip155:8453",
"maxAmountRequired": "1000000",
"resource": "https://api.example.com/data/premium",
"description": "Premium data feed access",
"mimeType": "application/json",
"payTo": "0xYourWalletAddress",
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Extract the PAYMENT-REQUIRED header (base64-encoded):
curl -s -D - http://localhost:3000/api/v1/weather/full 2>&1 | grep -i payment-required
# PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6MSwiYWNjZXB0cyI6Wy...
The guide includes a fail-open pattern that serves paid content when the facilitator is unavailable, even though verification did not succeed. In a payment-gated API context, this creates a clear authorization bypass: an attacker can exploit facilitator outages or induced failures to obtain premium content without paying.
const result = await facilitatorClient.verify(xPayment, requirements);
if (!result.valid && result.error.includes('Circuit breaker')) {
// Facilitator is down -- serve content but log for reconciliation
console.warn('[x402] FAIL OPEN: serving content without verification');
logUnverifiedPayment(xPayment, requirements);
return { serve: true, unverified: true };
}
The dataset download route is presented as paid content, but the attached dependency is instantiated with price_usd=0 and the promised dynamic override is not applied in the shown route. If copied as written, merchants may unintentionally expose paid datasets for free, causing direct revenue loss and bypass of the intended paywall.
No suspicious patterns detected.