Commit f8df92e
fix(x402-buyer): propagate upstream status/body and log every request (#504)
* fix(x402-buyer): propagate upstream status/body and log every request
During a live demo against inference.v1337.org/services/aeon, the upstream
responded with HTTP 403 + body "error code: 1010" (Cloudflare WAF blocking
on User-Agent). LiteLLM surfaced this as:
ServiceUnavailableError: OpenAIException - Payment verification failed
That misclassification cost ~30 min of debugging before someone called the
sidecar directly and saw the actual 403/1010 body. The real fix is two parts:
1. Structured per-request logging: every outbound RoundTrip now emits a log
line with method, URL, status code, duration, and a 512-byte body excerpt:
x402-buyer: outbound POST https://.../ → 403 (no payment required) body="error code: 1010"
x402-buyer: outbound POST https://.../ (with X-PAYMENT) → 403 after 42ms body="error code: 1010" — passing through upstream error
x402-buyer: outbound POST https://.../ (with X-PAYMENT) → 200 after 38ms
Transport-level errors (dial failures, TLS) are also logged.
2. Non-402 non-2xx status codes are passed through verbatim: the sidecar
already returned the upstream response object unchanged in both the
probe path (first request, no X-PAYMENT) and the retry path (after
X-PAYMENT). No status remapping was happening in proxy.go — the
"Payment verification failed" came from Traefik's x402-verifier
ForwardAuth (forwardauth.go:147), not the buyer. The per-request log
now gives operators the evidence they need to distinguish "verifier
blocked" from "upstream blocked" without having to port-forward and
call the sidecar manually.
The 402-retry payment signing behaviour is unchanged: the sidecar still
intercepts 402 probe responses, attaches X-PAYMENT, and retries. Only
the observability and error-surface for non-402 non-2xx is improved.
Adds TestUpstreamStatusPropagation table test: 7 subtests covering 200/403/
404/503 (direct) and 200/403/500 (after payment retry). All 35 buyer tests pass.
* fix(x402-buyer): sanitize user-controlled log inputs (CWE-117)
Addresses CodeQL alerts 4483-4487 from PR #504 review. The 5 new
log.Printf calls added for upstream error visibility interpolated
req.Method, req.URL, and err directly — an attacker-controlled
upstream could embed CR/LF to inject fake log entries (log forging).
Adds sanitizeLogString() which replaces any code point < 0x20 or
== 0x7f with '_', then wraps every user-controlled argument (Method,
URL.String(), err.Error()) in that helper before interpolation.
The body excerpt was already %q-escaped and is not changed.
Unit test covers \n, \r, \t, \x00, \x1b, DEL, printable ASCII, and
UTF-8 multi-byte letters.
---------
Co-authored-by: bussyjd <bussyjd@users.noreply.github.com>1 parent 7fd7d49 commit f8df92e
2 files changed
Lines changed: 305 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
425 | 425 | | |
426 | 426 | | |
427 | 427 | | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
428 | 468 | | |
429 | 469 | | |
430 | 470 | | |
| |||
440 | 480 | | |
441 | 481 | | |
442 | 482 | | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
443 | 487 | | |
444 | 488 | | |
445 | 489 | | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
446 | 498 | | |
447 | 499 | | |
448 | 500 | | |
| |||
531 | 583 | | |
532 | 584 | | |
533 | 585 | | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
534 | 591 | | |
535 | 592 | | |
536 | 593 | | |
| |||
545 | 602 | | |
546 | 603 | | |
547 | 604 | | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
548 | 614 | | |
549 | 615 | | |
550 | 616 | | |
551 | 617 | | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
552 | 624 | | |
553 | 625 | | |
554 | 626 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2124 | 2124 | | |
2125 | 2125 | | |
2126 | 2126 | | |
| 2127 | + | |
| 2128 | + | |
| 2129 | + | |
| 2130 | + | |
| 2131 | + | |
| 2132 | + | |
| 2133 | + | |
| 2134 | + | |
| 2135 | + | |
| 2136 | + | |
| 2137 | + | |
| 2138 | + | |
| 2139 | + | |
| 2140 | + | |
| 2141 | + | |
| 2142 | + | |
| 2143 | + | |
| 2144 | + | |
| 2145 | + | |
| 2146 | + | |
| 2147 | + | |
| 2148 | + | |
| 2149 | + | |
| 2150 | + | |
| 2151 | + | |
| 2152 | + | |
| 2153 | + | |
| 2154 | + | |
| 2155 | + | |
| 2156 | + | |
| 2157 | + | |
| 2158 | + | |
| 2159 | + | |
| 2160 | + | |
| 2161 | + | |
| 2162 | + | |
| 2163 | + | |
| 2164 | + | |
| 2165 | + | |
| 2166 | + | |
| 2167 | + | |
| 2168 | + | |
| 2169 | + | |
| 2170 | + | |
| 2171 | + | |
| 2172 | + | |
| 2173 | + | |
| 2174 | + | |
| 2175 | + | |
| 2176 | + | |
| 2177 | + | |
| 2178 | + | |
| 2179 | + | |
| 2180 | + | |
| 2181 | + | |
| 2182 | + | |
| 2183 | + | |
| 2184 | + | |
| 2185 | + | |
| 2186 | + | |
| 2187 | + | |
| 2188 | + | |
| 2189 | + | |
| 2190 | + | |
| 2191 | + | |
| 2192 | + | |
| 2193 | + | |
| 2194 | + | |
| 2195 | + | |
| 2196 | + | |
| 2197 | + | |
| 2198 | + | |
| 2199 | + | |
| 2200 | + | |
| 2201 | + | |
| 2202 | + | |
| 2203 | + | |
| 2204 | + | |
| 2205 | + | |
| 2206 | + | |
| 2207 | + | |
| 2208 | + | |
| 2209 | + | |
| 2210 | + | |
| 2211 | + | |
| 2212 | + | |
| 2213 | + | |
| 2214 | + | |
| 2215 | + | |
| 2216 | + | |
| 2217 | + | |
| 2218 | + | |
| 2219 | + | |
| 2220 | + | |
| 2221 | + | |
| 2222 | + | |
| 2223 | + | |
| 2224 | + | |
| 2225 | + | |
| 2226 | + | |
| 2227 | + | |
| 2228 | + | |
| 2229 | + | |
| 2230 | + | |
| 2231 | + | |
| 2232 | + | |
| 2233 | + | |
| 2234 | + | |
| 2235 | + | |
| 2236 | + | |
| 2237 | + | |
| 2238 | + | |
| 2239 | + | |
| 2240 | + | |
| 2241 | + | |
| 2242 | + | |
| 2243 | + | |
| 2244 | + | |
| 2245 | + | |
| 2246 | + | |
| 2247 | + | |
| 2248 | + | |
| 2249 | + | |
| 2250 | + | |
| 2251 | + | |
| 2252 | + | |
| 2253 | + | |
| 2254 | + | |
| 2255 | + | |
| 2256 | + | |
| 2257 | + | |
| 2258 | + | |
| 2259 | + | |
| 2260 | + | |
| 2261 | + | |
| 2262 | + | |
| 2263 | + | |
| 2264 | + | |
| 2265 | + | |
| 2266 | + | |
| 2267 | + | |
| 2268 | + | |
| 2269 | + | |
| 2270 | + | |
| 2271 | + | |
| 2272 | + | |
| 2273 | + | |
| 2274 | + | |
| 2275 | + | |
| 2276 | + | |
| 2277 | + | |
| 2278 | + | |
| 2279 | + | |
| 2280 | + | |
| 2281 | + | |
| 2282 | + | |
| 2283 | + | |
| 2284 | + | |
| 2285 | + | |
| 2286 | + | |
| 2287 | + | |
| 2288 | + | |
| 2289 | + | |
| 2290 | + | |
| 2291 | + | |
| 2292 | + | |
| 2293 | + | |
| 2294 | + | |
| 2295 | + | |
| 2296 | + | |
| 2297 | + | |
| 2298 | + | |
| 2299 | + | |
| 2300 | + | |
| 2301 | + | |
| 2302 | + | |
| 2303 | + | |
| 2304 | + | |
| 2305 | + | |
| 2306 | + | |
| 2307 | + | |
| 2308 | + | |
| 2309 | + | |
| 2310 | + | |
| 2311 | + | |
| 2312 | + | |
| 2313 | + | |
| 2314 | + | |
| 2315 | + | |
| 2316 | + | |
| 2317 | + | |
| 2318 | + | |
| 2319 | + | |
| 2320 | + | |
| 2321 | + | |
| 2322 | + | |
| 2323 | + | |
| 2324 | + | |
| 2325 | + | |
| 2326 | + | |
| 2327 | + | |
| 2328 | + | |
| 2329 | + | |
| 2330 | + | |
| 2331 | + | |
| 2332 | + | |
| 2333 | + | |
| 2334 | + | |
| 2335 | + | |
| 2336 | + | |
| 2337 | + | |
| 2338 | + | |
| 2339 | + | |
| 2340 | + | |
| 2341 | + | |
| 2342 | + | |
| 2343 | + | |
| 2344 | + | |
| 2345 | + | |
| 2346 | + | |
| 2347 | + | |
| 2348 | + | |
| 2349 | + | |
| 2350 | + | |
| 2351 | + | |
| 2352 | + | |
| 2353 | + | |
| 2354 | + | |
| 2355 | + | |
| 2356 | + | |
| 2357 | + | |
| 2358 | + | |
| 2359 | + | |
0 commit comments