Skip to content

Exclude null and wildcard from external matching - #19494

Open
ryandiginomad wants to merge 1 commit into
spring-projects:mainfrom
ryandiginomad:gh-19072
Open

Exclude null and wildcard from external matching#19494
ryandiginomad wants to merge 1 commit into
spring-projects:mainfrom
ryandiginomad:gh-19072

Conversation

@ryandiginomad

@ryandiginomad ryandiginomad commented Aug 2, 2026

Copy link
Copy Markdown

ExternalInetAddressMatcher is defined as !InternalInetAddressMatcher, and the internal matcher returns false for a null address and for the wildcard addresses 0.0.0.0 and :: — they are neither loopback, link-local, site-local, nor ULA, so they fall through to the final return false. Negating that classified all three as external, which is what gh-19072 reports.

This returns false for those cases before delegating, so they now match neither matchExternal() nor matchInternal(). That asymmetry looks deliberate to me: none of the three identifies a host a request could originate from, so neither classification is meaningful — but if you would rather the wildcard addresses count as internal, that is a one-line change instead.

InetAddress.isAnyLocalAddress() covers both wildcard forms. I checked the IPv4-mapped spelling too, since it is the easy one to miss:

0.0.0.0          -> Inet4Address   anyLocal=true   loopback=false  siteLocal=false
::               -> Inet6Address   anyLocal=true   loopback=false  siteLocal=false
::ffff:0.0.0.0   -> Inet4Address   anyLocal=true   loopback=false  siteLocal=false
::1              -> Inet6Address   anyLocal=false  loopback=true   siteLocal=false
127.0.0.1        -> Inet4Address   anyLocal=false  loopback=false  siteLocal=false
8.8.8.8          -> Inet4Address   anyLocal=false  loopback=false  siteLocal=false

The JDK folds ::ffff:0.0.0.0 into an Inet4Address, so it is covered by the same check, and loopback/public addresses are untouched.

Closes gh-19072

Testing

Three tests added to ExternalInetAddressMatcherTests, following the surrounding naming convention and @ValueSource style: one for matches((InetAddress) null) and a parameterized one for 0.0.0.0 and ::. I confirmed all three fail on main before the change and pass after it.

./gradlew :spring-security-core:check is green — 1507 tests across 185 classes, 0 failures, checkstyle clean. I ran it with -PtestToolchain=21 because I do not have JDK 25 locally; options.release is 17 regardless.

matchExternal and ExternalInetAddressMatcher have no other callers in the repository, so the change is contained to this API.

🤖 AI assistance

Developed with Claude Code. I reviewed every line of this diff, and the verification above reflects test runs I actually performed and observed.

ExternalInetAddressMatcher negates InternalInetAddressMatcher, which
returns false for a null address and for the wildcard addresses 0.0.0.0
and ::. Negating that classified all three as external, even though none
of them identifies a host that a request could originate from.

Return false for those cases before delegating to the internal matcher,
and document the behavior on matchExternal.

Closes spring-projectsgh-19072

Signed-off-by: Ryan Tang <24728770+ryandiginomad@users.noreply.github.com>
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Aug 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: waiting-for-triage An issue we've not yet triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

InetAddressMatchers.matchExternal() matches null and 0.0.0.0

2 participants