IpInetAddressMatcher throws ArrayIndexOutOfBoundsException instead of returning false for mismatched IPv4/IPv6 families
Describe the bug
IpInetAddressMatcher.matches(InetAddress) (introduced in 7.1, backing IpAddressMatcher/InetAddressMatchers) can throw ArrayIndexOutOfBoundsException instead of returning false when the address being checked and the configured address are of different IP families (IPv4 vs. IPv6).
The class-level Javadoc on IpAddressMatcher states:
a matcher which is configured with an IPv4 address will never match a request which returns an IPv6 address, and vice-versa.
The current implementation doesn't enforce this at the byte-array level:
byte[] remAddr = toCheck.getAddress();
byte[] reqAddr = this.requiredAddress.getAddress();
int nMaskFullBytes = this.nMaskBits / 8;
byte finalByte = (byte) (0xFF00 >> (this.nMaskBits & 0x07));
for (int i = 0; i < nMaskFullBytes; i++) {
if (remAddr[i] != reqAddr[i]) {
return false;
}
}There's no check that remAddr.length == reqAddr.length. If the configured CIDR mask requires more full bytes than the shorter of the two addresses has (e.g. an IPv6 /64 matcher checked against an IPv4 address), and the leading bytes happen to be equal up to the shorter array's length, the loop indexes past the end of the shorter array.
To Reproduce
IpAddressMatcher matcher = new IpAddressMatcher("2001:db8::/64");
// 32.1.13.184's bytes (0x20, 0x01, 0x0d, 0xb8) equal the first 4 bytes of 2001:0db8::,
// so the comparison loop doesn't short-circuit before running past the 4-byte array.
matcher.matches("32.1.13.184");This throws:
java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4
at org.springframework.security.util.matcher.IpInetAddressMatcher.matches(IpInetAddressMatcher.java:100)instead of returning false.
Expected behavior
matches() should return false when the two addresses belong to different families, per the documented contract, instead of throwing.
Sample
I have a fix ready (add a length check on the two byte arrays before comparing them) plus regression tests, and will open a PR referencing this issue.
Source: spring-projects/spring-security