fix(crypto): reject malformed hex in timingSafeEqualHex - #661
Conversation
|
Note Gittensory Gate skippedPR closed before full evaluation. No late first comment was created.
💰 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. |
This comment has been minimized.
This comment has been minimized.
99c91e1 to
0f09d92
Compare
| expect(timingSafeEqualHex("ab12", "ab13")).toBe(false); | ||
| expect(timingSafeEqualHex("ab12", "ab1234")).toBe(false); | ||
| expect(timingSafeEqualHex("zz", "00")).toBe(false); | ||
| expect(timingSafeEqualHex("abc", "def")).toBe(true); |
There was a problem hiding this comment.
P0: Test asserts timing-safe hex comparison returns true for unequal malformed inputs
Test expects timingSafeEqualHex("abc","def") to be true, but the underlying hexToBytes returns empty arrays for odd-length strings, making any two malformed odd-length hex strings compare equal.
Fix hexToBytes to explicitly reject malformed input and update the test to expect false for unequal odd-length strings.
AI prompt
Check if this security scanner issue is valid. If so, understand the root cause and fix it. If appropriate, update or add tests. Keep the change focused and preserve intended behavior.
<file name="test/unit/crypto.test.ts">
<violation number="1" location="test/unit/crypto.test.ts:18">
<priority>P0</priority>
<title>Test asserts timing-safe hex comparison returns true for unequal malformed inputs</title>
<evidence>The test currently expects timingSafeEqualHex("abc", "def") to return true. However, the underlying hexToBytes function in src/utils/crypto.ts returns an empty Uint8Array when hex.length % 2 !== 0. Consequently, timingSafeEqualHex receives two zero-length arrays, skips the comparison loop, and returns true. This means any two odd-length hex strings—including completely different values—compare as equal, breaking the security guarantees of the function.</evidence>
<recommendation>Fix hexToBytes to throw an error (or return a sentinel value handled by timingSafeEqualHex) when given malformed/odd-length hex input, so that timingSafeEqualHex never silently returns true for unequal malformed strings. Then update the test to expect false (or an exception) for timingSafeEqualHex("abc", "def").</recommendation>
</violation>
</file>
b7d02eb to
2df15c2
Compare
There was a problem hiding this comment.
PR #661 — test(crypto): cover sha256, hex compare, and base64url helpers
Verdict: REQUEST CHANGES
Resolves issue: N/A (test-only)
CI: validate/test/lint/workers success, BUT Superagent Security Scan = action_required (real concern, not informational). gittensory/Context neutral.
Highlights:
- Otherwise-reasonable coverage for sha256Hex (format + determinism), base64UrlEncode (string + bytes, no padding), and the equal/unequal/length-mismatch branches of timingSafeEqualHex.
Concerns / required changes:
- BLOCKER — P0 STILL PRESENT on current head (verified test/unit/crypto.test.ts line 19 + src/utils/crypto.ts): the test asserts timingSafeEqualHex("abc","def") === true. Both inputs are odd-length, so hexToBytes returns an empty Uint8Array for each; equal length (0) + empty loop -> result 0 -> true. This codifies as "expected" that two DIFFERENT malformed hex strings compare equal. Since verifyGitHubSignature delegates to timingSafeEqualHex, it locks in a webhook-signature-verification weakness.
- Required fix: malformed/odd-length hex must NOT compare equal — either hexToBytes signals invalidity (and timingSafeEqualHex returns false on invalid input), or the test asserts === false and the implementation is corrected to match. Do not merge a test that ratifies the broken behavior.
Completeness vs issue: As pure coverage it is broad, but it actively asserts insecure behavior as correct, so it must not be merged in its current form.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #661 +/- ##
==========================================
- Coverage 96.60% 96.60% -0.01%
==========================================
Files 109 109
Lines 14895 14898 +3
Branches 5384 5386 +2
==========================================
+ Hits 14390 14392 +2
Misses 104 104
- Partials 401 402 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
5096cd4 to
b3794d7
Compare
JSONbored
left a comment
There was a problem hiding this comment.
Good:
- Adds useful crypto helper coverage around sha256, base64url, normal equality, unequal hex, and length mismatch.
- Normal CI/Codecov are green.
Bad:
- Existing owner review requested changes, still unresolved.
- Superagent Security Scan is ACTION_REQUIRED.
- Test asserts timingSafeEqualHex("abc", "def") === true, codifying that two different malformed odd-length hex strings compare equal.
- verifyGitHubSignature delegates to timingSafeEqualHex, so this locks in webhook-signature weakness.
Change requests:
- Make malformed/odd-length hex compare false.
- Update implementation and test together; do not merge a test that ratifies the broken behavior.
- Add explicit invalid hex/empty hex coverage once semantics are fixed.
Fail closed when either operand is empty, odd-length, or non-hex so unequal malformed digests cannot compare equal (webhook verification). Updates tests for sha256/base64url helpers accordingly. Co-authored-by: Cursor <cursoragent@cursor.com>
201be19 to
2ad8d59
Compare
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Addressed the review feedback:
Ready for another look when you have a moment. |
Co-authored-by: Cursor <cursoragent@cursor.com>
|
|
JSONbored
left a comment
There was a problem hiding this comment.
Hi there, codecov CI is still failing due to inadequate test coverage, can you please resolve this. Thanks!
|
reviewbot · advisory review Reviewed 2 changed file(s) — two independent AI reviewers. Changed files: Suggested action: ✅ Safe to merge — both reviewers found no blocking issues. Reviewer A · Suggestions
Worth double-checking
Reviewer B · Suggestions
Worth double-checking
|
Summary
timingSafeEqualHexnow fails closed on empty, odd-length, or non-hex operands (fixes webhook signature weakness flagged in review)verifyGitHubSignaturecases for malformedsha256=digestsReview feedback addressed
abcvsdef) compare equalverifyGitHubSignaturedelegating to weak comparison is resolved at the sourceTest plan
npm test -- test/unit/crypto.test.ts