This is an automated email from the ASF dual-hosted git repository. chibenwa pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-jspf.git
commit 0d4bb9430a47743439ff0dd2512535384e90bde6 Author: Quan Tran <[email protected]> AuthorDate: Fri Oct 30 16:30:55 2026 +0700 [FIX] ip4/ip6 mechanisms: an overflowing CIDR length is a permerror The regex accepts any number of digits as the CIDR length, so ip4:192.0.2.1/4294967296 or ip6:2001:db8::/99999999999 made Integer.parseInt throw NumberFormatException out of the parser: the check ended as neutral instead of permerror (RFC 7208 5.6). Reject a length of more than 3 digits before parsing it, as /33 is. --- .../org/apache/james/jspf/terms/IP4Mechanism.java | 4 ++++ .../org/apache/james/jspf/SPFExecutorBaseTest.java | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/resolver/src/main/java/org/apache/james/jspf/terms/IP4Mechanism.java b/resolver/src/main/java/org/apache/james/jspf/terms/IP4Mechanism.java index 44c17f6..b483255 100644 --- a/resolver/src/main/java/org/apache/james/jspf/terms/IP4Mechanism.java +++ b/resolver/src/main/java/org/apache/james/jspf/terms/IP4Mechanism.java @@ -68,6 +68,10 @@ public class IP4Mechanism extends GenericMechanism { int maskLength = getMaxCidr(); if (params.groupCount() >= 2 && params.group(2) != null) { String maskLengthString = params.group(2); + // the regex accepts any number of digits: more than 3 are invalid, and could overflow an int + if (maskLengthString.length() > 3) { + throw new PermErrorException("Invalid CIDR: " + maskLengthString); + } maskLength = Integer.parseInt(maskLengthString); if (maskLength > getMaxCidr() || (maskLengthString.length() > 1 && maskLengthString.startsWith("0"))) { diff --git a/resolver/src/test/java/org/apache/james/jspf/SPFExecutorBaseTest.java b/resolver/src/test/java/org/apache/james/jspf/SPFExecutorBaseTest.java index 1e7ac25..f56e270 100644 --- a/resolver/src/test/java/org/apache/james/jspf/SPFExecutorBaseTest.java +++ b/resolver/src/test/java/org/apache/james/jspf/SPFExecutorBaseTest.java @@ -58,6 +58,12 @@ public abstract class SPFExecutorBaseTest { return Paths.get(zonesDir, zoneFile).toAbsolutePath().toString(); } + private SPFResult checkRecord(String hostname, String record, String ipAddress) throws IOException { + FakeResolver fakeResolver = new FakeResolver(); + fakeResolver.addRecord(new TXTRecord(Name.fromString(hostname + "."), DClass.IN, 30L, record)); + return createCustomSPF(new DNSServiceXBillImpl(fakeResolver)).checkSPF(ipAddress, "a_user@" + hostname, hostname); + } + @Test public void test() { SPF spf = createSPF(); @@ -450,4 +456,18 @@ public abstract class SPFExecutorBaseTest { assertEquals(SPFErrorConstants.PASS_CONV, result.getResult()); } + + @Test(timeout = 10000) + public void shouldReturnPermErrorOnIp4CidrOverflowingAnInt() throws IOException { + SPFResult result = checkRecord("ip4CidrOverflow.spfexecutor.fake", "v=spf1 ip4:192.0.2.1/4294967296 -all", "1.2.3.4"); + + assertEquals(SPFErrorConstants.PERM_ERROR_CONV, result.getResult()); + } + + @Test(timeout = 10000) + public void shouldReturnPermErrorOnIp6CidrOverflowingAnInt() throws IOException { + SPFResult result = checkRecord("ip6CidrOverflow.spfexecutor.fake", "v=spf1 ip6:2001:db8::/99999999999 -all", "1.2.3.4"); + + assertEquals(SPFErrorConstants.PERM_ERROR_CONV, result.getResult()); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
