Spigniv73 opened a new issue, #14152:
URL: https://github.com/apache/apisix/issues/14152

   ## Summary
   
   `ai-proxy` forwards the client's `Transfer-Encoding: chunked` header to the 
upstream, but the body it
   sends is **not** chunked. `content-length` is explicitly stripped by the 
same blacklist, so the
   upstream receives a framing contradiction and a real HTTP/1.1 server rejects 
it with `400`.
   
   ## Where (pin `b6deb41`; identical in release 3.19.0)
   
   `apisix/plugins/ai-transport/http.lua:86-91` — the blacklist that is 
supposed to remove hop-by-hop
   framing headers:
   
   ```lua
   local blacklist = {
       "host",
       "content-length",
       "accept-encoding",
   }
   ```
   
   `transfer-encoding` is missing. Every other client header is copied
   (`apisix/plugins/ai-proxy/base.lua:291` → `extra_opts.client_headers = 
core.request.headers(ctx)`,
   merged at `apisix/plugins/ai-providers/base.lua:237`). The body is then a 
known Lua string, so the
   transport sends it unchunked.
   
   ## Repro (hard)
   
   ```bash
   # transport client using the real construct_forward_headers, rawdump 
upstream on :8889
   curl -s -X POST 'http://127.0.0.1:9083/poc?port=8889' -H 'Transfer-Encoding: 
chunked' -H 'X-Foo: a' -d 'xxxxxxxx'
   # against a real nginx upstream that reads the body (:9082/echo)
   curl -s -X POST 'http://127.0.0.1:9083/poc?port=9082' -H 'Transfer-Encoding: 
chunked' -d 'xxxxxxxx'
   ```
   
   Observed on the rawdump:
   
   ```
   POST /echo HTTP/1.1
   transfer-encoding: chunked          <-- and no Content-Length
   ...
   <raw JSON body, not chunked>
   ```
   
   → real nginx upstream: `status=400`. Without the client header: 
`Content-Length: 62` + raw body →
   `status=200`.
   
   ## Impact
   
   Any client that legitimately uses chunked upload against an `ai-proxy` route 
can get a `400` from the
   upstream, i.e. the request never reaches the model. CVSS 3.1
   `AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L` = 6.5.
   
   CWE-436 / CWE-444.
   
   ## Suggestion
   
   Either add `transfer-encoding` to the blacklist (the body is re-framed 
anyway, so it should not be
   forwarded verbatim), or actually chunk the body when the header is passed 
through. Adding it to the
   blacklist matches the existing intent, since `content-length` is treated the 
same way.
   
   ## Notes
   
   Found while auditing `b6deb41`; `apisix/plugins/ai-transport/http.lua` is 
byte-identical to the
   3.19.0 release commit and unchanged on `main` today. Introduced by 
`be45f233` (three-layer AI proxy
   refactor, #13170). A sibling report about the same forwarded-header path 
(`ai-cache` fingerprint)
   is filed separately.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to