Repository navigation
fix(antd-elixir): move to grpc 1.0.5 past the critical Hex advisory, commit mix.lock (V2-1574) - #375
Conversation
grpc < 1.0 carries GHSA-grp7-v8xh-rj7h (critical, unsafe term deserialization in the server-side Erlpack codec) plus three high-severity server-side advisories, all fixed in 1.0.0. antd-elixir is client-only and does not reach the vulnerable code, but every install resolved 0.11.5 and Hex flagged it. - grpc ~> 1.0.5; grpc 1.0 split the client from the server, and gun is now an optional dependency of it, so gun ~> 2.4.0 is listed explicitly. grpc_server (test only) supplies the mock servers. - Antd.GrpcAdapter rewritten for grpc 1.0's Gun adapter, which reads a call's response from a per-stream StreamResponseProcess instead of the caller's mailbox. Still needed: 1.0.5 drops headers and trailers on a failed unary call as 0.11.5 did. - Commit mix.lock (un-ignored for antd-elixir only) so CI and dev resolve one tree; the constraints in mix.exs are what protect downstream users. cowlib 2.21.0 / gun (EEF-CVE-2026-43966, medium) has no fixed release and stays flagged by hex.audit; see the ticket. Full suite on dev2: 265 tests, 0 failures, 3 skipped, before and after. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dirvine
left a comment
There was a problem hiding this comment.
APPROVE — incremental PR #375 change
Reviewed exact head 947bd983219edca8dba9db5beb0aba5ad2606fc4 against preview base bc339abe3e8914104139cf63253913892ed28432, not the whole #367 fan-out.
5/6 reviewed — partial panel; provisional conclusion, not full consensus. GLM 5.3 and Qwen 3.8 completed correctness and adversarial reviews and support approval. Missing: DS4 correctness; each missing role returned an incomplete, output-truncated response on its initial attempt and one narrower same-model retry. Failed attempts are not votes. DS4 completed its other role and also supports approval.
No introduced blocking defect found. The adapter now drains the per-stream response process and replays into Gun's decoder while retaining failure metadata. The replay cleanup is in an after block; no-header and streaming calls still delegate unchanged. The source's raw-response/Gun-response tuple difference is resolved by Gun's private await normalization bridge, not an adapter mismatch.
Independently executed
- macOS, Erlang/OTP 29, Elixir 1.20.4; exact committed lockfile, no tracked source edits.
mix test --seed 0: 262 passed, 3 skipped, on both head and a fresh base dependency resolution.- Production compile and application startup passed.
grpc_serverandcowboyare absent from the loaded production applications. - 10 additional review-only probes passed, covering metadata/error parity, timeout/dead process handling and a 40-way synthetic replay-isolation check. These are not live-daemon tests or committed regressions.
git diff --checkpassed. The changed-file formatter check fails ingrpc_client.exon both head and base; inherited formatting drift.
Non-blocking risks / follow-ups
- The security audit is still non-clean.
mix hex.auditexits 1 for medium CVE-2026-43966 / GHSA-w4f7-4cxr-rv3c in gun/cowlib. The fresh base has the same exposure plus four grpc advisories, including one critical. Source checks support non-reachability through this SDK's default client path, not a global claim about downstream applications. Patched cowlib availability was not independently verified. - The declared Elixir
~> 1.14floor does not match resolved dependency requirements. Fresh base resolution already has this drift; document/test the supported minimum in a follow-up. No old-runtime build was run. - The adapter depends on grpc internals. The
~> 1.0.5constraint limits minor upgrades but does not prove future patch compatibility; keep the documented pointer/manifest regression gate for every upgrade. One small cleanup: an unexpected transport message gets an extra diagnostic wrapper on replay. An additional executedgun_inform103 probe confirms both upstream and adapter still return UNKNOWN (2), with empty adapter metadata. Preserve the original cause and add a regression fixture in a follow-up. The suggested total-timeout regression is not supported: the old adapter also reset its wait for each frame.
Integration boundary
No CI check runs or statuses are reported for this head. No live Rust daemon or Linux execution was tested. #367 merged during this review at bc339abe3e8914104139cf63253913892ed28432 (the reviewed base). #375 still targets nic/stack-integration-preview, while main has since advanced: retarget/rebase onto main and rerun checks against the actual destination. This approves the reviewed incremental code, not an untested post-retarget integration tree or a merge/release.
V2-1574. antd-elixir moves off grpc 0.11.5, which carries a critical Hex advisory, to grpc 1.0.5.
Stacked on #367 (base
nic/stack-integration-preview), becauseAntd.GrpcAdapterand the gRPC pointer/manifest tests this has to re-run exist only in the fan-out. This PR gets retargeted tomainonce #367 lands.Advisories (
mix hex.audit, cross-checked with GHSA and OSV)GRPC.Codec.Erlpack.decode/2: barebinary_to_termCowboy.Handler.read_full_body/1: unbounded bodyGRPC.Server.Transcode: path-binding overrideGRPC.Compressor.Gzip.decompress/1: gzip bombcow_http_struct_hd:escape_string/2: CRLF in a structured header built from attacker inputReachability: none reachable from this client-only SDK
GRPC.Codec.Proto, andAntd.GrpcClientnever passescodec:.read_full_bodyand Transcode: server only. Nothing inlib/usesGRPC.Server; only the test mock servers do.accepted_compressorslists the encoding. That defaults to[], and antd-elixir sets neithercompressor:noraccepted_compressors:.cow_http_hdparsers, never the vulnerable structured-header encoder. The REST client goes through req, finch and mint, which don't involve cowlib.So the upgrade is hygiene plus defence in depth. It's still worth doing: every fresh install currently resolves the critical release.
Change
mix.exs:{:grpc, "~> 1.0.5"}. From 1.0, grpc is split into a client package andgrpc_server, and gun becomes optional.{:gun, "~> 2.4.0"}, which grpc requires.{:grpc_server, "~> 1.0.5", only: :test}for the mock servers.Antd.GrpcAdapterrewritten, behaviour unchanged. grpc 1.0.5 still drops the headers and trailers of a failed unary call, so the adapter stays; thex-antd-error-codetrailer depends on it.StreamResponseProcessrather than the caller's mailbox, so the old approach of scooping messages from the mailbox hung.receive_data/2decode them.~> 1.0.5.mix.lockis now committed, with!antd-elixir/mix.lockadded to.gitignore.mix.exsconstraints are what protect users.Verified on dev2 (Erlang 29 / Elixir 1.19.5)
grpc_pointers_test.exs: 38/38, including "the adapter returns a failed call's metadata only when asked".grpc_manifests_test.exs: 10/10, including the over-4 MiB round trip.mix hex.auditnow reports only the cowlib/gun advisory.Open points
mix hex.auditstays non-clean. The proposal is to accept it on the reachability above and watch for a cowlib release after 2.21.0.?=, which needs OTP ≥ 26, so a fresh install fails on OTP 25.mix.exssayselixir: "~> 1.14". A README note or a stated minimum is a follow-up.~> 1.0.5vs~> 1.0: the tighter range protects the adapter. The cost is a conflict for downstream projects that need grpc 1.1 until the adapter is revalidated.Closes V2-1574.
🤖 Generated with Claude Code