Skip to content

fix(deps): bump h2 to 0.4.16 for RUSTSEC-2026-0258 - #368

Open
Vasanthdev2004 wants to merge 1 commit into
mainfrom
fix/h2-unbounded-data-frames
Open

fix(deps): bump h2 to 0.4.16 for RUSTSEC-2026-0258#368
Vasanthdev2004 wants to merge 1 commit into
mainfrom
fix/h2-unbounded-data-frames

Conversation

@Vasanthdev2004

Copy link
Copy Markdown
Collaborator

What breaks

cargo audit fails on every branch as of today:

Crate:     h2
Title:     h2 unbounded empty DATA frames
ID:        RUSTSEC-2026-0258
Solution:  Upgrade to >=0.4.16
error: 1 vulnerability found!

The advisory was published after main's last green run, so the SUCCESS ticks currently showing on open PRs are stale cached results, not evidence. Anything that re-runs CI goes red until this lands — #331 already has.

h2 arrives transitively via hyper, so there is no manifest change. The lockfile is the entire fix.

Why this is hand-edited

cargo update -p h2 on my machine produced the h2 bump plus nine unrelated rewrites, all downgrades:

crate from to pulled in by
syn 2.0.117 1.0.109 data-encoding-macro-internal
windows-sys 0.61.2 0.52.0 errno (×3)
socket2 0.6.3 0.5.10 (×3)

--precise 0.4.16 produced the identical set, so it is not collateral re-resolution from an unpinned update — it is local crates.io index drift against whatever generated main's lockfile. Those downgrades have nothing to do with the advisory and do not belong in a security bump, so this commit changes only h2's version and checksum lines.

That cargo check --locked accepts the result is the proof that 0.4.16 introduces no dependency changes of its own — a hand-edited lockfile that got that wrong would fail --locked immediately.

Worth someone re-running cargo update on a Linux box to see whether those nine entries are real drift in main's lockfile or an artifact of my toolchain. Either way it is a separate question from this fix.

Verification

  • cargo check --locked --workspace — exit 0
  • cargo tree --locked -p h2 — resolves h2 v0.4.16
  • Full suite on a branch carrying the Windows test-gating fix: gitlawb-core 104, gl 328, git-remote-gitlawb 58, all passing

cargo check --locked --workspace --all-targets cannot run from main on Windows — the unix-only test code does not compile there, which is exactly what #330's first commit fixes. Linux CI covers that path.

Scope

Deliberately kept to the advisory alone rather than folded into #331, so it can land on its own and unblock every open PR at once.

`cargo audit` started failing on every branch today: h2 0.4.13 is vulnerable to
RUSTSEC-2026-0258, "h2 unbounded empty DATA frames", fixed in 0.4.16. The
advisory was published after main's last green run, so the existing green ticks
on open PRs are stale results rather than evidence — anything that re-runs CI
goes red until this lands.

h2 arrives transitively through hyper, so no manifest changes: the lockfile is
the whole fix.

Edited by hand rather than with `cargo update -p h2`, deliberately. Running the
update on this machine also rewrote nine unrelated entries — `syn` 2.0.117 to
1.0.109 for data-encoding-macro-internal, `windows-sys` 0.61.2 to 0.52.0 for
errno, `socket2` 0.6.3 to 0.5.10 in three places — all DOWNGRADES, and all
still present with `--precise 0.4.16`. That is local index drift against
whatever generated main's lockfile, not something this fix needs, and it does
not belong in a security bump. Only h2's `version` and `checksum` lines change
here; `cargo check --locked` accepting the result is what confirms 0.4.16 needs
no dependency changes of its own.

Verified with `cargo check --locked --workspace` (exit 0) and, on a branch that
carries the Windows test-gating fix, the full suite: gitlawb-core 104, gl 328,
git-remote-gitlawb 58. `--all-targets` cannot be checked from main on Windows
because the unix-only test code does not compile there, which is what #330's
first commit fixes; Linux CI covers it.
@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a22759dd-a712-4e65-9033-8ac1d80fe764

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@beardthelion beardthelion added the kind:bug Defect fix — wrong or unsafe behavior label Aug 18, 2026
@Vasanthdev2004

Copy link
Copy Markdown
Collaborator Author

Adding the blast radius, since the green ticks elsewhere make this look less urgent than it is.

Every open PR is affected. Most just have not noticed yet.

cargo audit re-evaluates against the live advisory database on each run, so a PR's result reflects when it last ran, not the state of its code. The advisory landed today between two runs:

last green run #285, 2026-08-18T05:44:10Z
first red run #327, 2026-08-18T08:35:05Z

Two PRs have re-run cargo audit since. Both went red, both on RUSTSEC-2026-0258:

The other 21 open PRs still show SUCCESS, all from runs that predate the advisory — some from July. Those are cached results, not passing checks. Each one flips red the next time anything triggers CI: a push, a rebase, a re-run, a base update. Nothing about their code has to change.

So the count of visibly-broken PRs will keep climbing on its own, and each author will independently hit a red check that has nothing to do with their work and costs them time to diagnose. That is the real cost here, more than the vulnerability itself — h2 reaches us transitively through hyper, and the DoS surface is a matter for deployed nodes rather than for CI.

The change is two lines, both inside h2's lockfile entry — version and checksum. No manifest change, no code change. cargo check --locked passing is itself the proof that 0.4.16 needs no dependency changes of its own; a wrong hand-edit would fail --locked immediately.

18/18 checks green here, including cargo audit.

Happy to answer anything on the hand-edit rationale (the nine unrelated downgrades cargo update wanted to bring along are in the description). If someone would rather do this differently — a full cargo update -p h2 on a Linux box, or folding it into a dependency sweep — that is fine by me and I will close this; the goal is that it lands, not that it lands this way.

@Vasanthdev2004

Copy link
Copy Markdown
Collaborator Author

@kevincodex1 — could you take a look when you get a moment?

Two-line lockfile diff, 18/18 green. It is blocking #327 and #331 today, and the remaining 21 open PRs go red on their next CI trigger regardless of their own changes (detail in the comment above).

No rush if you would rather it went in differently — happy to close this in favour of another approach.

@beardthelion beardthelion left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified the two changed lines rather than the CI ticks.

The checksum is the real one: sha256 of the h2-0.4.16 tarball from static.crates.io is a9f37a958b41b3b19ee2707c06439c0e9e547e847223eb791ecb0cb821c65e27, byte-identical to the line this adds, and the sparse index agrees. 0.4.16 is the advisory's minimum patched version, so this is the smallest bump that clears RUSTSEC-2026-0258. h2's normal dependency set is unchanged between 0.4.13 and 0.4.16, and the one requirement that moved (http ^1 to ^1.1) is satisfied by the locked http 1.4.0, so leaving the entry's dependency block untouched is correct.

I ran it both ways. Reverting the two lines takes cargo audit to exit 1 on RUSTSEC-2026-0258; restoring them, exit 0. Corrupting one hex digit of the new checksum takes cargo fetch --locked to exit 101 with a checksum error, and it does that with the crate warm in the registry cache and with no network at all. So your cargo check --locked was already sufficient proof that the hand-edited checksum matches what the registry publishes.

On your open question: it is not your toolchain. From main's lockfile on a Linux box, cargo update -p h2 --precise 0.4.16 gives the h2 bump byte-identical to your hand edit plus exactly the same seven rewrites. They are not crate downgrades, which is why they look worse than they are. syn, socket2 and windows-sys each already exist at both versions in main's lockfile, and what moves is which duplicate a consumer's edge points at. rustix, tempfile and errno declare windows-sys ">=0.52, <0.62" and data-encoding-macro-internal declares syn ">=1, <4", so both choices are legal.

They are also not caused by your bump. Running cargo update -p h2 --precise 0.4.13, the version main already pins, produces the identical seven changes with h2 itself untouched. So main's committed lockfile is not a fixed point of the current resolver and index, and any command that rewrites it re-normalizes those edges; the crate you name is incidental. Both lockfiles pass cargo metadata --locked. Nothing is drifting, hand-editing was the right call, and there is no separate issue to file.

One scope note, no change needed here: merging this re-runs nothing on the other open PRs, so their stale green ticks stay stale until each pushes or enters the merge queue. Nothing can land on a red audit regardless, since the checks run again on the merge group.

Worth knowing that CodeRabbit skipped this rather than cleared it, since Cargo.lock sits behind its default !**/*.lock filter.


Edited to correct two things in my original text. I had written that "cargo re-unifies downward when it rewrites the file" as the explanation for the seven rewrites; I never verified that and have retracted it rather than replacing it with another guess. What is verified is the no-op-update result above, which is the more useful fact anyway. I had also framed the dependency block as correct "not only because --locked accepted it" and described purging the registry cache as part of the checksum test; both undersold your own evidence, since --locked catches a bad checksum warm and offline.

@beardthelion

Copy link
Copy Markdown
Collaborator

@kevincodex1 LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind:bug Defect fix — wrong or unsafe behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants