fix(git): widen is_safe_refname alphabet to include + and @ (#4194) - #4257
fix(git): widen is_safe_refname alphabet to include + and @ (#4194)#4257iroiro147 wants to merge 1 commit into
Conversation
…k#4194) `git check-ref-format` accepts `+` and `@` in ref components (no newline, no NUL, no control chars, no `.` at the start of a component, no trailing `/`), but `is_safe_refname` rejected anything outside `[a-zA-Z0-9_./-]`. Real-world upstream branches like `OriginTrail/dkg`'s `refs/heads/test/842+841-devnet` were un-mirrorable into Buzz git. Both characters have no meaning to the object-store key scheme or to path traversal (`.`-based traversal protection is unchanged, and refnames are still pinned to the `refs/` prefix so they cannot escape into other key spaces). The predicate is shared symmetrically by write-side `validate` and read-side hydration, so widening once fixes both sides of the seam. Keep the widening conservative — the other git-legal chars called out in the issue (`=`, `,`, `!`, `]`) are not observed failing at any upstream mirror and remain excluded to preserve a small attack surface. They can be added in a follow-up if a real failure surfaces. Regression coverage extends the existing `safe_refnames` tests in both `manifest.rs` and `hydrate.rs`: - positive: `refs/heads/test/842+841-devnet` and `refs/tags/release@v1` - negative: `=`, `,`, `!`, `]` remain rejected `cargo check -p buzz-relay` and `cargo test -p buzz-relay --lib safe_refnames` are green (2/2 tests pass; the 10 unrelated pre-existing failures in api::media + telemetry suites are untouched and out of scope). Refs block#4194 Signed-off-by: Sarthak Singh <sarthak.singh@juspay.in>
|
@bayees Approval landed at 05:24Z but merge is |
|
Cross-linking #4214, which addresses the same issue — flagging one interaction so it's visible whichever PR moves forward: Two small ones in this diff: the removed |
|
Verified on the deployment that hit #4194 (we mirror
Two tiny non-blocking notes:
|
|
Thanks @alanshurafa — excellent catches. The follow-up is now on a new branch ( Three items folded in:
Test counts green: 2/2 safe_refnames + 11/11 manifest_event + 35/35 git_perms. Will close this PR and open a fresh one against |
|
Superseded by follow-up PR — see comment above. Closing so the new head is unambiguous. |
What
git check-ref-format --branch "test/842+841-devnet"exits 0 — git considers that branch name legal. Buzz rejected it, along with every other ref containing+or@, becauseis_safe_refnameallowed only[a-zA-Z0-9_./-]. The motivating case:OriginTrail/dkg's branchrefs/heads/test/842+841-devnetwas the single ref out of 1,339 that couldn't be mirrored into Buzz git (push → HTTP 400).This widens
is_safe_refnameto[a-zA-Z0-9_./+-@]. Both characters have no meaning to Buzz's object-store key scheme or path-traversal guard —..and//remain forbidden, leading/trailing//rules are unchanged, and therefs/prefix constraint keeps refnames out of other key spaces. The predicate is shared symmetrically by write-sideManifest::validateand read-side hydrate, so widening it once fixes both directions of the CAS seam (the "valid CAS, un-clone-able output" hazard the original predicate was designed to avoid).The wider universe of git-legal refname characters is left closed:
=,,,!,]are legal to git but un-observed in wild mirrors and excluded here as conservative hardening. If a real case surfaces, the same test-and-widen pattern applies.Tests
Extends the existing
safe_refnamesunit tests in bothcrates/buzz-relay/src/api/git/manifest.rsandcrates/buzz-relay/src/api/git/hydrate.rs:refs/heads/test/842+841-devnet,refs/tags/release@v1refs/heads/feat=v2,refs/heads/feat,name,refs/heads/feat!hot,refs/heads/feat]branchall still rejectedcargo check -p buzz-relay— clean.cargo test -p buzz-relay --lib safe_refnames— 2/2 passed.The 10 pre-existing failures in
api::media/telemetrysuites are untouched and unrelated (seecargo test -p buzz-relay --libbaseline).Linked issue
Refs #4194