镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Reject host names in SubnetUtils6 instead of resolving them via DNS - #417

Open
Sahana2524 wants to merge 1 commit into
apache:masterfrom
Sahana2524:subnetutils6-no-dns
Open

Sahana2524 wants to merge 1 commit into
apache:masterfrom
Sahana2524:subnetutils6-no-dns

Conversation

@Sahana2524

Copy link
Copy Markdown

SubnetUtils6 turns its string input into bytes with InetAddress.getByName(), which falls back to a DNS lookup for anything that is not an IP literal. SubnetInfo.isInRange(String) and the SubnetUtils6(String) constructors are documented to take an IPv6 address, but today they also accept host names:

  • new SubnetUtils6("2001:db8::/32").getInfo().isInRange("attacker.example") returns true when that name has an AAAA record in 2001:db8::/32. If an application checks a client-supplied value against an allowlist (for example a forwarded-for header), sending a name the client controls passes the check.
  • Every such call also makes the server resolve a name chosen by the client, and "" is mapped to the loopback address.

The IPv4 SubnetUtils already parses with a regex and never resolves names, so this brings SubnetUtils6 in line with it. The new check only lets through strings shaped like an IPv6 literal (hex digits and a colon first, optional brackets and %scope). For those, getByName() always parses the literal and never does a lookup. Bracketed and scoped literals keep working.

Repro (JDK 18+ resolver SPI mapping attacker.example to 2001:db8::5), before and after:

isInRange("attacker.example") = true          # [DNS lookup] attacker.example
isInRange("attacker.example") -> IAE: Could not parse [attacker.example] - not an IPv6 address

About the test: testHostNameIsNotResolved always passes with the fix because no lookup happens. Without the fix it fails only where one of the names resolves to IPv6. That happens with ip6-localhost on typical Linux hosts, or with -DargLine=-Djava.net.preferIPv6Addresses=true, which is how I confirmed it locally. This touches the same toBytes() helper as #412 (IPv4-mapped literals). The two changes are independent, and mapped literals like ::ffff:192.0.2.1 still match the new pattern.

Thanks for your contribution to Apache Commons! Your help is appreciated!

Before you push a pull request, review this list:

  • Read the contribution guidelines for this project.
  • Read the ASF Generative Tooling Guidance if you use Artificial Intelligence (AI).
  • I used AI to create any part of, or all of, this pull request. Which AI tool was used to create this pull request, and to what extent did it contribute?
    Claude Code (Anthropic) found this issue and drafted the fix, the test and this description. I reviewed all of it before submitting.
  • Run a successful build using the default Maven goal with mvn; that's mvn on the command line by itself.
  • Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible, but it is a best practice.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Each commit in the pull request should have a meaningful subject line and body. Note that a maintainer may squash commits during the merge process.

SubnetUtils6 parsed its input with InetAddress.getByName(), which resolves
anything that is not an IP literal through DNS. A host name with an AAAA
record inside the subnet made SubnetInfo.isInRange(String) return true,
and each call could trigger a lookup of a caller-supplied name. Only
accept strings shaped like an IPv6 literal, as SubnetUtils does for IPv4.
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