T09 · Insecure Skill Coding Practices
- Location
agent_pay_client/payer.py:160- Finding
L402 Automatic Payment Can Bypass the Configured Spending Ceiling
- Content
View full analysis
config.max_l402_sats): return PaymentResult( success=False, protocol=PaymentProtocol.L402, error=f"Invoice amount {req.amount_sats} sats exceeds configured max_l402_sats " f"({config.max_l402_sats}) — refusing to pay.", ) ``` ### Technical Analysis The documented safety model states that every automatic Lightning payment is subject to an explicit `max_l402_sats` ceiling. However, `amount_sats` is populated only from an optional JSON response field. It is not derived from or validated against the BOLT11 invoice that the LND node will actually pay. When `amount_sats` is absent, `req.amount_sats` remains `None`. The expression: ```python req.amount_sats and req.amount_sats > config.max_l402_sats ``` then evaluates to a false value, allowing execution to continue to the LND payment request. Consequently, the code treats an unknown amount as acceptable rather than failing closed. Even when the JSON field is present, a malicious server could potentially report an amount lower than the amount encoded in the invoice. The companion JSON field is server-controlled and is not an authoritative source for enforcing a financial limit. ### Attack Path 1. A caller deliberately enables `lightnin ...[truncated 1178 chars]- Remediation
View remediation
config.max_l402_sats: return PaymentResult( success=False, protocol=PaymentProtocol.L402, error="Invoice exceeds the configured spending ceiling.", ) ``` ]]>
