Skip to content

Commit 7288fec

Browse files
committed
Verify ipAddress Not A Hostname
Closes gh-15172
1 parent db9f593 commit 7288fec

File tree

2 files changed

+30
-8
lines changed

2 files changed

+30
-8
lines changed

web/src/main/java/org/springframework/security/web/util/matcher/IpAddressMatcher.java

+14-7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.net.InetAddress;
2020
import java.net.UnknownHostException;
21+
import java.util.Scanner;
2122

2223
import jakarta.servlet.http.HttpServletRequest;
2324

@@ -47,7 +48,7 @@ public final class IpAddressMatcher implements RequestMatcher {
4748
* come.
4849
*/
4950
public IpAddressMatcher(String ipAddress) {
50-
assertStartsWithHexa(ipAddress);
51+
assertNotHostName(ipAddress);
5152
if (ipAddress.indexOf('/') > 0) {
5253
String[] addressAndMask = StringUtils.split(ipAddress, "/");
5354
ipAddress = addressAndMask[0];
@@ -68,7 +69,7 @@ public boolean matches(HttpServletRequest request) {
6869
}
6970

7071
public boolean matches(String address) {
71-
assertStartsWithHexa(address);
72+
assertNotHostName(address);
7273
InetAddress remoteAddress = parseAddress(address);
7374
if (!this.requiredAddress.getClass().equals(remoteAddress.getClass())) {
7475
return false;
@@ -91,11 +92,17 @@ public boolean matches(String address) {
9192
return true;
9293
}
9394

94-
private void assertStartsWithHexa(String ipAddress) {
95-
Assert.isTrue(
96-
ipAddress.charAt(0) == '[' || ipAddress.charAt(0) == ':'
97-
|| Character.digit(ipAddress.charAt(0), 16) != -1,
98-
"ipAddress must start with a [, :, or a hexadecimal digit");
95+
private void assertNotHostName(String ipAddress) {
96+
String error = "ipAddress " + ipAddress + " doesn't look like an IP Address. Is it a host name?";
97+
Assert.isTrue(ipAddress.charAt(0) == '[' || ipAddress.charAt(0) == ':'
98+
|| Character.digit(ipAddress.charAt(0), 16) != -1, error);
99+
if (!ipAddress.contains(":")) {
100+
Scanner parts = new Scanner(ipAddress);
101+
parts.useDelimiter("[./]");
102+
while (parts.hasNext()) {
103+
Assert.isTrue(parts.hasNextInt() && parts.nextInt() >> 8 == 0, error);
104+
}
105+
}
99106
}
100107

101108
private InetAddress parseAddress(String address) {

web/src/test/java/org/springframework/security/web/util/matcher/IpAddressMatcherTests.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.springframework.mock.web.MockHttpServletRequest;
2323

2424
import static org.assertj.core.api.Assertions.assertThat;
25+
import static org.assertj.core.api.Assertions.assertThatException;
2526
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
2627

2728
/**
@@ -108,7 +109,21 @@ public void ipv6RequiredAddressMaskTooLongThenIllegalArgumentException() {
108109
@Test
109110
public void invalidAddressThenIllegalArgumentException() {
110111
assertThatIllegalArgumentException().isThrownBy(() -> new IpAddressMatcher("invalid-ip"))
111-
.withMessage("ipAddress must start with a [, :, or a hexadecimal digit");
112+
.withMessage("ipAddress invalid-ip doesn't look like an IP Address. Is it a host name?");
113+
}
114+
115+
// gh-15172
116+
@Test
117+
public void hexadecimalDomainNameThenIllegalArgumentException() {
118+
assertThatException().isThrownBy(() -> new IpAddressMatcher("deadbeef.abc"))
119+
.withMessage("ipAddress deadbeef.abc doesn't look like an IP Address. Is it a host name?");
120+
}
121+
122+
// gh-15172
123+
@Test
124+
public void numericDomainNameThenIllegalArgumentException() {
125+
assertThatException().isThrownBy(() -> new IpAddressMatcher("123.156.7.18.org"))
126+
.withMessage("ipAddress 123.156.7.18.org doesn't look like an IP Address. Is it a host name?");
112127
}
113128

114129
}

0 commit comments

Comments
 (0)