Skip to content

Reject an in-addr.arpa name longer than 32 characters before splitting it - #228

Merged
beaugunderson merged 2 commits into
mainfrom
bg-fromarpa-length
Oct 1, 2026
Merged

beaugunderson merged 2 commits into
mainfrom
bg-fromarpa-length

Conversation

@beaugunderson

@beaugunderson beaugunderson commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

Address4.fromArpa() split, reversed and joined its whole argument before handing the result to the constructor, so the constructor's 15-character limit ran only after work proportional to the input. On node 24.19.0 that is about 8 ms per MB: 33 ms for 4 MB, 259 ms for 32 MB. Address6.fromArpa() rejects the same strings in under 0.01 ms, because its nibble grammar is checked first.

The fix

Address4.fromArpa() checks the length of its argument on entry and throws AddressError above 32 characters. That is the longest name the constructor accepts: a 15-character address, a /32 prefix length on its last octet (the RFC 2317 classless form, as in 0/25.2.0.192.in-addr.arpa.) and .in-addr.arpa..

Every name that parsed before still parses. A longer one threw AddressError before and throws it now, with a message naming the 32-character limit.

Tests

A new input length block under fromArpa covers the longest name, the RFC 2317 form, and rejection of names one character over the limit, a 34-character run of labels, and 1 MiB of dots. The rejection test fails before the fix.

Reported by @manus-pi via GHSA-24hj-7547-x7wc, declined as an advisory and fixed as hardening: the cost is linear in the input and up to about 8 times its size in memory, which is what splitting any string costs, and it takes megabytes in a field that holds at most 32 characters to notice.

…g it

Address4.fromArpa() split, reversed and joined its whole argument before
handing the result to the constructor, so the constructor's 15-character
limit ran only after work proportional to the input: about 8 ms per MB
(node 24.19.0), against under 0.01 ms for the same string in
Address6.fromArpa(), whose nibble grammar rejects it first.

The longest name the constructor accepts is a 15-character address, a
"/32" prefix length on its last octet (the RFC 2317 classless form) and
".in-addr.arpa.": 32 characters. Anything longer is rejected on entry.
Every name that parsed before still parses; a longer one throws
AddressError as it did, with a message naming the 32-character limit.
@beaugunderson
beaugunderson merged commit 09b8072 into main Oct 1, 2026
6 checks passed
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.

1 participant