fix(crypto): reject invalid hex operands in timingSafeEqualHex - #1760
Conversation
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review result - approve/merge recommendedReview updated: 2026-06-29 21:43:37 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 3 non-blocking
Review context
Contributor next steps
Signal definitions
🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Summary
timingSafeEqualHexso distinct invalid hex strings no longer compare equal.hexToBytesfail behavior withsrc/orb/relay.ts(returnnull/falseon invalid input instead of an empty byte array).Closes #ISSUE_NUMBER (open a bug issue first — none exists yet for this).
Bug
In
src/utils/crypto.ts,hexToBytesreturns an emptyUint8Arrayfor invalid hex:Two different invalid strings (e.g.
"zz"vs"yy", or"not-hex-a"vs"not-hex-b") both parse to length-0 arrays, sotimingSafeEqualHexreturnstrue. That violates the contract of a constant-time equality check and diverges fromsrc/orb/relay.ts, where invalid hex causes verification to fail.Current call sites (
verifyGitHubSignature, draft OAuth state checks) always compare against valid 64-char SHA-256 hex on at least one side, so this is latent — but the exported primitive is incorrect and unsafe for reuse.Proposed fix
Scope
type(scope): short summaryConventional Commit format.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally;codecov/patchrequires ≥97% coverage of the lines AND branches you changednpm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderateIf any required check was skipped, explain why:
Safety
UI Evidencesection below. (N/A — crypto utility only)Test plan
test/unit/security-internals.test.ts(or a dedicatedcrypto.test.tsif one exists):timingSafeEqualHex("zz", "yy")→falsetimingSafeEqualHex("abc", "abcd")→false(odd length)timingSafeEqualHex(valid64, valid64)→truetimingSafeEqualHex(valid64a, valid64b)→falseverifyGitHubSignatureand draft OAuth still pass.npm run test:cigreen.Files to change
src/utils/crypto.tsnullfromhexToByteson invalid input; fail closed intimingSafeEqualHextest/unit/security-internals.test.tsor newtest/unit/crypto.test.tsNotes
src/orb/relay.tshexToBytesreturnsnullon invalid hex and callers treat that as verification failure.