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]