浏览代码

Verify ipAddress Not A Hostname

Closes gh-15172
Josh Cummings 1 年之前
父节点
当前提交
7288fecc24

+ 14 - 7
web/src/main/java/org/springframework/security/web/util/matcher/IpAddressMatcher.java

@@ -18,6 +18,7 @@ package org.springframework.security.web.util.matcher;
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.util.Scanner;
 
 import jakarta.servlet.http.HttpServletRequest;
 
@@ -47,7 +48,7 @@ public final class IpAddressMatcher implements RequestMatcher {
 	 * come.
 	 */
 	public IpAddressMatcher(String ipAddress) {
-		assertStartsWithHexa(ipAddress);
+		assertNotHostName(ipAddress);
 		if (ipAddress.indexOf('/') > 0) {
 			String[] addressAndMask = StringUtils.split(ipAddress, "/");
 			ipAddress = addressAndMask[0];
@@ -68,7 +69,7 @@ public final class IpAddressMatcher implements RequestMatcher {
 	}
 
 	public boolean matches(String address) {
-		assertStartsWithHexa(address);
+		assertNotHostName(address);
 		InetAddress remoteAddress = parseAddress(address);
 		if (!this.requiredAddress.getClass().equals(remoteAddress.getClass())) {
 			return false;
@@ -91,11 +92,17 @@ public final class IpAddressMatcher implements RequestMatcher {
 		return true;
 	}
 
-	private void assertStartsWithHexa(String ipAddress) {
-		Assert.isTrue(
-				ipAddress.charAt(0) == '[' || ipAddress.charAt(0) == ':'
-						|| Character.digit(ipAddress.charAt(0), 16) != -1,
-				"ipAddress must start with a [, :, or a hexadecimal digit");
+	private void assertNotHostName(String ipAddress) {
+		String error = "ipAddress " + ipAddress + " doesn't look like an IP Address. Is it a host name?";
+		Assert.isTrue(ipAddress.charAt(0) == '[' || ipAddress.charAt(0) == ':'
+				|| Character.digit(ipAddress.charAt(0), 16) != -1, error);
+		if (!ipAddress.contains(":")) {
+			Scanner parts = new Scanner(ipAddress);
+			parts.useDelimiter("[./]");
+			while (parts.hasNext()) {
+				Assert.isTrue(parts.hasNextInt() && parts.nextInt() >> 8 == 0, error);
+			}
+		}
 	}
 
 	private InetAddress parseAddress(String address) {

+ 16 - 1
web/src/test/java/org/springframework/security/web/util/matcher/IpAddressMatcherTests.java

@@ -22,6 +22,7 @@ import org.junit.jupiter.api.Test;
 import org.springframework.mock.web.MockHttpServletRequest;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatException;
 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
 
 /**
@@ -108,7 +109,21 @@ public class IpAddressMatcherTests {
 	@Test
 	public void invalidAddressThenIllegalArgumentException() {
 		assertThatIllegalArgumentException().isThrownBy(() -> new IpAddressMatcher("invalid-ip"))
-			.withMessage("ipAddress must start with a [, :, or a hexadecimal digit");
+			.withMessage("ipAddress invalid-ip doesn't look like an IP Address. Is it a host name?");
+	}
+
+	// gh-15172
+	@Test
+	public void hexadecimalDomainNameThenIllegalArgumentException() {
+		assertThatException().isThrownBy(() -> new IpAddressMatcher("deadbeef.abc"))
+			.withMessage("ipAddress deadbeef.abc doesn't look like an IP Address. Is it a host name?");
+	}
+
+	// gh-15172
+	@Test
+	public void numericDomainNameThenIllegalArgumentException() {
+		assertThatException().isThrownBy(() -> new IpAddressMatcher("123.156.7.18.org"))
+			.withMessage("ipAddress 123.156.7.18.org doesn't look like an IP Address. Is it a host name?");
 	}
 
 }