Skip to content

Commit d464f13

Browse files
[+] Validate IPs of appservers CactuseSecurity#3024
1 parent 076d7d2 commit d464f13

File tree

4 files changed

+134
-3
lines changed

4 files changed

+134
-3
lines changed

roles/database/files/sql/idempotent/fworch-texts.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3108,6 +3108,10 @@ INSERT INTO txt VALUES ('E5415', 'German', 'Passwort muss mindestens ein Sonder
31083108
INSERT INTO txt VALUES ('E5415', 'English', 'Password must contain at least one special character (!?(){}=~$%&#*-+.,_)');
31093109
INSERT INTO txt VALUES ('E5421', 'German', 'Schlüssel nicht gefunden oder Wert nicht konvertierbar: Wert wird gesetzt auf: ');
31103110
INSERT INTO txt VALUES ('E5421', 'English', 'Key not found or could not convert value to int: taking value: ');
3111+
INSERT INTO txt VALUES ('E5422', 'German', 'Eintrag enthält nicht alle erforderlichen Spalten');
3112+
INSERT INTO txt VALUES ('E5422', 'English', 'Entry does not contain all required columns');
3113+
INSERT INTO txt VALUES ('E5423', 'German', 'IP-Adresse/IP-Bereich ist fehlerhaft');
3114+
INSERT INTO txt VALUES ('E5423', 'English', 'IP Address/IP Range malformed');
31113115

31123116
INSERT INTO txt VALUES ('E6001', 'German', 'Der Re-Login war nicht erfolgreich. Haben Sie ein falsches Passwort eingegeben? Schauen Sie für Details bitte in die Logs.');
31133117
INSERT INTO txt VALUES ('E6001', 'English', 'Re-login failed. Did you enter a wrong password? See log for details.');

roles/lib/files/FWO.Basics/IpOperations.cs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Net.Sockets;
22
using System.Net;
33
using NetTools;
4+
using System;
45

56
namespace FWO.Basics
67
{
@@ -39,6 +40,115 @@ public static (string, string) SplitIpToRange(string ipString)
3940
return (ipStart, ipEnd);
4041
}
4142

43+
public static bool TryParseIPStringToRange(this string ipString, out (string Start, string End) ipRange, bool strictv4Parse = false)
44+
{
45+
ipRange = default;
46+
47+
try
48+
{
49+
(string ipStart, string ipEnd) = SplitIpToRange(ipString);
50+
51+
bool ipStartOK = IPAddress.TryParse(ipStart, out IPAddress? ipAdressStart);
52+
bool ipEndOK = IPAddress.TryParse(ipEnd, out IPAddress? ipAdressEnd);
53+
54+
if(ipAdressStart is null || ipAdressEnd is null)
55+
{
56+
return false;
57+
}
58+
59+
if(strictv4Parse && ipAdressStart?.AddressFamily == AddressFamily.InterNetwork && ipAdressEnd?.AddressFamily == AddressFamily.InterNetwork)
60+
{
61+
if(!IsValidIPv4(ipStart) || !IsValidIPv4(ipEnd))
62+
{
63+
return false;
64+
}
65+
}
66+
67+
if(!ipStartOK || !ipEndOK)
68+
{
69+
return false;
70+
}
71+
72+
if(!IPAddress.TryParse(ipStart, out _) || !IPAddress.TryParse(ipEnd, out _))
73+
{
74+
return false;
75+
}
76+
77+
ipRange.Start = ipStart;
78+
ipRange.End = ipEnd;
79+
80+
return true;
81+
}
82+
catch(Exception)
83+
{
84+
return false;
85+
}
86+
}
87+
88+
public static bool TryParseIPString<T>(this string ipString, out T? ipResult, bool strictv4Parse = false)
89+
{
90+
ipResult = default;
91+
92+
try
93+
{
94+
(string ipStart, string ipEnd) = SplitIpToRange(ipString);
95+
96+
bool ipStartOK = IPAddress.TryParse(ipStart, out IPAddress? ipAdressStart);
97+
bool ipEndOK = IPAddress.TryParse(ipEnd, out IPAddress? ipAdressEnd);
98+
99+
if(ipAdressStart is null || ipAdressEnd is null)
100+
{
101+
return false;
102+
}
103+
104+
if(strictv4Parse && ipAdressStart?.AddressFamily == AddressFamily.InterNetwork && ipAdressEnd?.AddressFamily == AddressFamily.InterNetwork)
105+
{
106+
if(!IsValidIPv4(ipStart) || !IsValidIPv4(ipEnd))
107+
{
108+
return false;
109+
}
110+
}
111+
112+
if(!ipStartOK || !ipEndOK)
113+
{
114+
return false;
115+
}
116+
117+
if(typeof(T) == typeof((string, string)))
118+
{
119+
ipResult = (T)Convert.ChangeType((ipAdressStart.ToString(), ipAdressEnd.ToString()), typeof(T));
120+
return true;
121+
}
122+
else if(typeof(T) == typeof(IPAddressRange) && IPAddressRange.TryParse(ipString, out IPAddressRange ipRange))
123+
{
124+
ipResult = (T)Convert.ChangeType(ipRange, typeof(T));
125+
return true;
126+
}else if(typeof(T) == typeof((IPAddress, IPAddress)))
127+
{
128+
Tuple<IPAddress, IPAddress>? ipTuple = new(ipAdressStart, ipAdressEnd);
129+
ipResult = (T)Convert.ChangeType(ipTuple, typeof(T));
130+
return true;
131+
}
132+
133+
return false;
134+
}
135+
catch(Exception)
136+
{
137+
return false;
138+
}
139+
}
140+
141+
private static bool IsValidIPv4(string ipAddress)
142+
{
143+
byte[] addBytes = [.. ipAddress.Split('.').Where(_ => byte.Parse(_) <= 255 && byte.Parse(_) >= 0).Select(byte.Parse)];
144+
if(addBytes.Length != 4) return false;
145+
foreach(var b in addBytes)
146+
{
147+
if(b < 0 || b > 255) return false;
148+
}
149+
return true;
150+
}
151+
42152
public static string GetObjectType(string ip1, string ip2)
43153
{
44154
ip1 = ip1.StripOffUnnecessaryNetmask();

roles/ui/files/FWO.UI/Data/CSVAppServerImportModel.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using FWO.Basics;
1+
using FWO.Basics;
22
using FWO.Data.Modelling;
33

44
namespace FWO.Ui.Data
@@ -16,6 +16,11 @@ public CSVAppServerImportModel (string ipString)
1616
(AppIPRangeStart, AppIPRangeEnd) = IpOperations.SplitIpToRange(ipString);
1717
}
1818

19+
public CSVAppServerImportModel()
20+
{
21+
22+
}
23+
1924
public ModellingAppServer ToModellingAppServer()
2025
{
2126
return new ModellingAppServer()

roles/ui/files/FWO.UI/Services/FileUploadService.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public async Task ReadFileToBytes(InputFileChangeEventArgs args)
7474

7575
if(!TryGetEntries(line, ';', out string[] entries) && !TryGetEntries(line, ',', out entries))
7676
{
77-
error.Message = "Entry doesn't contain all required columns";
77+
error.Message = UserConfig.GetText("E5422");
7878
errors.Add(error);
7979

8080
continue;
@@ -83,8 +83,20 @@ public async Task ReadFileToBytes(InputFileChangeEventArgs args)
8383
if (IsHeader(entries))
8484
continue;
8585

86-
CSVAppServerImportModel importAppServer = new(entries[3])
86+
string ipString = entries[3];
87+
88+
if(!ipString.TryParseIPString<(string, string)>(out (string Start, string End) ipRange, strictv4Parse: true))
89+
{
90+
error.Message = UserConfig.GetText("E5423");
91+
errors.Add(error);
92+
93+
continue;
94+
}
95+
96+
CSVAppServerImportModel importAppServer = new()
8797
{
98+
AppIPRangeStart = ipRange.Start,
99+
AppIPRangeEnd = ipRange.End,
88100
AppID = entries[1],
89101
AppServerTyp = entries[2]
90102
};

0 commit comments

Comments
 (0)