Skip to content

[MEDIUM] Classify rooted IPs and bound hostname normalization - #41

Open
OskarEichler wants to merge 1 commit into
knu:masterfrom
OskarEichler:codex/security-normalize-hostname-bounds
Open

[MEDIUM] Classify rooted IPs and bound hostname normalization#41
OskarEichler wants to merge 1 commit into
knu:masterfrom
OskarEichler:codex/security-normalize-hostname-bounds

Conversation

@OskarEichler

Copy link
Copy Markdown
Contributor

Summary

  • Classify rooted IPv4 and bracketed IPv6 hosts after removing one trailing root dot.
  • Reject DNS hostnames longer than 253 characters and labels longer than 63 characters.
  • Recheck the byte limits after IDN/Punycode encoding.

Why

IP detection currently runs before the trailing root dot is removed. As a result, 127.0.0.1. becomes a domain object with registered domain 0.1 instead of an IP object. A caller that resolves or otherwise canonicalizes the rooted host can therefore apply domain-oriented policy to an IP address; the focused reproduction showed an HTTP cookie with Domain=.0.1 being accepted for that origin.

The Punycode encoder also does quadratic work on large inputs with many distinct code points. Invalid oversized IDN labels reached that work through DomainName.new. The DNS limits stop such inputs before the expensive encode and validate the encoded result as well.

Measured on Ruby 4.0.6 before this change, distinct-code-point labels took approximately 0.095s at 1,000 characters, 0.383s at 2,000, 1.52s at 4,000, and 6.09s at 8,000.

Verification

  • Ruby 4.0.6: 13 tests, 660 assertions, 0 failures.
  • Ruby 3.2.11: 13 tests, 660 assertions, 0 failures.
  • Focused repro on both Rubies confirms rooted IPv4/IPv6 classification, cookie-domain rejection, pre/post-encoding label limits, total hostname limits, and acceptance of an exact 253-byte hostname.
  • ruby -c lib/domain_name.rb and git diff --check pass.

No test files were changed.

Compatibility

Breaking change: inputs outside the DNS 63-byte label and 253-byte hostname limits now raise ArgumentError. Valid DNS names retain their existing normalized output.

The lower-level DomainName::Punycode API remains available for non-hostname encoding; the bounds apply at the DomainName hostname boundary.

Sign up for freeto 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

@OskarEichler