Skip to content

fix(bindings): validate secret key hex length - #487

Closed
GrapeBaBa wants to merge 3 commits into
mainfrom
fix/secret-key-from-hex-length
Closed

fix(bindings): validate secret key hex length#487
GrapeBaBa wants to merge 3 commits into
mainfrom
fix/secret-key-from-hex-length

Conversation

@GrapeBaBa

@GrapeBaBa GrapeBaBa commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Validate SecretKey.fromHex input length before copying into its fixed-size buffer.
  • Require exactly 32 decoded bytes after stripping an optional 0x prefix.
  • Add regression coverage for prefixed and unprefixed valid keys, short and long inputs, odd-length hex, and non-ASCII input.

Why

Short hex strings previously reached a 32-byte slice operation without a length check, causing a ReleaseSafe bounds panic that aborted the Node process instead of throwing a JavaScript error. Checking the UTF-8 byte length before copying also prevents overlong strings from being silently truncated by N-API.

@GrapeBaBa
GrapeBaBa requested a review from a team as a code owner July 14, 2026 10:54
@GrapeBaBa
GrapeBaBa marked this pull request as draft July 14, 2026 11:25
@GrapeBaBa
GrapeBaBa marked this pull request as ready for review July 14, 2026 12:18
Comment thread bindings/napi/blst.zig

var hex_buf: [NativeSecretKey.serialize_size * 2 + 3]u8 = undefined;
const hex = try hexFromString(hex_string, &hex_buf);
if (hex.len != NativeSecretKey.serialize_size * 2) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this second check is ensuring that a non-0x-prefixed hex string thats the wrong length doesn't slip through

Comment thread bindings/napi/blst.zig

var hex_buf: [NativeSecretKey.serialize_size * 2 + 3]u8 = undefined;
const hex = try hexFromString(hex_string, &hex_buf);
if (hex.len != NativeSecretKey.serialize_size * 2) {

@spiral-ladder spiral-ladder Jul 16, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this is more suitable to be an assert, since if this check fails it means something is wrong with hexFromString and not the consumer input

program logic error = assert
input error = throw error

semes like a good practice to go by

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

  • "0x" + 31 bytes has length 64, but becomes 62 after removing the prefix.
  • An unprefixed 33-byte value has length 66 and remains 66.

Both pass the first check, so this should remain an input error rather than an assert.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

you're right, doesn't that mean hexFromString is misleading though because it accepts any string and returns it unchanged if it's not 0x prefixed

@spiral-ladder spiral-ladder left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

lgtm, but an item to maybe leave for further consideration is the semantics behind fromHexString. Maybe we should consider assuming that string inputs would be either length 62/64 and asserting first 2 chars are 0x prefixed?

@spiral-ladder

Copy link
Copy Markdown
Member

seems like your original commits are not signed @GrapeBaBa

@GrapeBaBa

Copy link
Copy Markdown
Contributor Author

Superseded by #517, recreated from the latest main with a single verified signed commit.

@GrapeBaBa GrapeBaBa closed this Jul 16, 2026
spiral-ladder pushed a commit that referenced this pull request Jul 16, 2026
## Summary

- validate `SecretKey.fromHex` input length before copying into its
fixed-size buffer
- require exactly 32 decoded bytes after stripping an optional `0x`
prefix
- cover prefixed and unprefixed valid keys, short and long inputs,
odd-length hex, and non-ASCII input

## Why

Short hex strings previously reached a 32-byte slice operation without a
length check, causing a ReleaseSafe bounds panic that aborted the Node
process instead of throwing a JavaScript error. Checking the UTF-8 byte
length before copying also prevents overlong strings from being silently
truncated by N-API.

Supersedes #487, which contains unsigned commits.
@wemeetagain
wemeetagain deleted the fix/secret-key-from-hex-length branch August 17, 2026 19:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants