diff --git a/src/Middleware/HttpOverrides/src/IPNetwork.cs b/src/Middleware/HttpOverrides/src/IPNetwork.cs
index 9c5ff7591ed2..94fad9d2d850 100644
--- a/src/Middleware/HttpOverrides/src/IPNetwork.cs
+++ b/src/Middleware/HttpOverrides/src/IPNetwork.cs
@@ -1,7 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
using System.Net;
+using System.Net.Sockets;
namespace Microsoft.AspNetCore.HttpOverrides
{
@@ -17,6 +19,8 @@ public class IPNetwork
/// The prefix length.
public IPNetwork(IPAddress prefix, int prefixLength)
{
+ CheckPrefixLengthRange(prefix, prefixLength);
+
Prefix = prefix;
PrefixLength = prefixLength;
PrefixBytes = Prefix.GetAddressBytes();
@@ -31,7 +35,7 @@ public IPNetwork(IPAddress prefix, int prefixLength)
private byte[] PrefixBytes { get; }
///
- /// The CIDR notation of the subnet mask
+ /// The CIDR notation of the subnet mask
///
public int PrefixLength { get; }
@@ -52,7 +56,7 @@ public bool Contains(IPAddress address)
var addressBytes = address.GetAddressBytes();
for (int i = 0; i < PrefixBytes.Length && Mask[i] != 0; i++)
{
- if (PrefixBytes[i] != (addressBytes[i] & Mask[i]))
+ if ((PrefixBytes[i] & Mask[i]) != (addressBytes[i] & Mask[i]))
{
return false;
}
@@ -79,5 +83,23 @@ private byte[] CreateMask()
return mask;
}
+
+ private static void CheckPrefixLengthRange(IPAddress prefix, int prefixLength)
+ {
+ if (prefixLength < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(prefixLength));
+ }
+
+ if (prefix.AddressFamily == AddressFamily.InterNetwork && prefixLength > 32)
+ {
+ throw new ArgumentOutOfRangeException(nameof(prefixLength));
+ }
+
+ if (prefix.AddressFamily == AddressFamily.InterNetworkV6 && prefixLength > 128)
+ {
+ throw new ArgumentOutOfRangeException(nameof(prefixLength));
+ }
+ }
}
}
diff --git a/src/Middleware/HttpOverrides/test/IPNetworkTest.cs b/src/Middleware/HttpOverrides/test/IPNetworkTest.cs
index cd5c37b906a9..4bd6aad4afb9 100644
--- a/src/Middleware/HttpOverrides/test/IPNetworkTest.cs
+++ b/src/Middleware/HttpOverrides/test/IPNetworkTest.cs
@@ -12,6 +12,15 @@ public class IPNetworkTest
[InlineData("174.0.0.0", 7, "175.1.1.10")]
[InlineData("10.174.0.0", 15, "10.175.1.10")]
[InlineData("10.168.0.0", 14, "10.171.1.10")]
+ [InlineData("192.168.0.1", 31, "192.168.0.0")]
+ [InlineData("192.168.0.1", 31, "192.168.0.1")]
+ [InlineData("192.168.0.1", 32, "192.168.0.1")]
+ [InlineData("192.168.1.1", 0, "0.0.0.0")]
+ [InlineData("192.168.1.1", 0, "255.255.255.255")]
+ [InlineData("2001:db8:3c4d::", 127, "2001:db8:3c4d::1")]
+ [InlineData("2001:db8:3c4d::1", 128, "2001:db8:3c4d::1")]
+ [InlineData("2001:db8:3c4d::1", 0, "::")]
+ [InlineData("2001:db8:3c4d::1", 0, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")]
public void Contains_Positive(string prefixText, int length, string addressText)
{
var network = new IPNetwork(IPAddress.Parse(prefixText), length);
@@ -23,6 +32,9 @@ public void Contains_Positive(string prefixText, int length, string addressText)
[InlineData("174.0.0.0", 7, "173.1.1.10")]
[InlineData("10.174.0.0", 15, "10.173.1.10")]
[InlineData("10.168.0.0", 14, "10.172.1.10")]
+ [InlineData("192.168.0.1", 31, "192.168.0.2")]
+ [InlineData("192.168.0.1", 32, "192.168.0.0")]
+ [InlineData("2001:db8:3c4d::", 127, "2001:db8:3c4d::2")]
public void Contains_Negative(string prefixText, int length, string addressText)
{
var network = new IPNetwork(IPAddress.Parse(prefixText), length);