Skip to content

Commit ca6118f

Browse files
committed
Enforce hostname and IPv6 validation on the static DHCP table
Only accept valid hostnames: Previously, invalid hostnames were trigerring the cell highlighting, but invalid entries were still accepted when using the green "save" button. Now, hostnames are saved only if they pass the validation, like other values. Only allow IPv6 enclosed in square brackets: The previous validation function used to validate IPv6 didn't accept brackets, resulting in errors when an IPv6 was typed directly on the table cell. A new function was created to validate IPv6 enclosed in brackets. Signed-off-by: RD WebDesign <[email protected]>
1 parent cce1e4b commit ca6118f

2 files changed

Lines changed: 29 additions & 14 deletions

File tree

scripts/js/settings-dhcp.js

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -261,13 +261,9 @@ function parseStaticDHCPLine(line) {
261261
const hwaddr = haveMAC ? parts[0].trim() : "";
262262

263263
// Check if the first or second part is a valid IPv4 or IPv6 address
264-
const hasSquareBrackets0 = parts[0][0] === "[" && parts[0].at(-1) === "]";
265-
const ipv60 = hasSquareBrackets0 ? parts[0].slice(1, -1) : parts[0];
266-
const hasSquareBrackets1 = parts.length > 1 && parts[1][0] === "[" && parts[1].at(-1) === "]";
267-
const ipv61 = hasSquareBrackets1 ? parts[1].slice(1, -1) : parts.length > 1 ? parts[1] : "";
268-
const firstIsValidIP = utils.validateIPv4(parts[0]) || utils.validateIPv6(ipv60);
264+
const firstIsValidIP = utils.validateIPv4(parts[0]) || utils.validateIPv6Brackets(parts[0]);
269265
const secondIsValidIP =
270-
parts.length > 1 && (utils.validateIPv4(parts[1]) || utils.validateIPv6(ipv61));
266+
parts.length > 1 && (utils.validateIPv4(parts[1]) || utils.validateIPv6Brackets(parts[1]));
271267
const ipaddr = firstIsValidIP ? parts[0].trim() : secondIsValidIP ? parts[1].trim() : "";
272268
const haveIP = ipaddr.length > 0;
273269

@@ -294,12 +290,13 @@ $(document).on("click", ".save-static-row", function () {
294290

295291
// Validate MAC and IP before saving
296292
const macValid = !hwaddr || utils.validateMAC(hwaddr);
297-
const ipValid = !ipaddr || utils.validateIPv4(ipaddr) || utils.validateIPv6(ipaddr);
298-
if (!macValid || !ipValid) {
293+
const ipValid = !ipaddr || utils.validateIPv4(ipaddr) || utils.validateIPv6Brackets(ipaddr);
294+
const nameValid = !hostname || utils.validateHostnameStrict(hostname);
295+
if (!macValid || !ipValid || !nameValid) {
299296
utils.showAlert(
300297
"error",
301298
"fa-times",
302-
"Cannot save: Invalid MAC or IP address",
299+
"Cannot save: Invalid value found on the table",
303300
"Please correct the highlighted fields before saving."
304301
);
305302
return;
@@ -505,7 +502,7 @@ $(document).on("input blur paste", "#StaticDHCPTable td.static-hwaddr", function
505502

506503
$(document).on("input blur paste", "#StaticDHCPTable td.static-ipaddr", function () {
507504
const val = $(this).text().trim();
508-
if (val && !(utils.validateIPv4(val) || utils.validateIPv6(val))) {
505+
if (val && !(utils.validateIPv4(val) || utils.validateIPv6Brackets(val))) {
509506
$(this).addClass("table-danger");
510507
$(this).attr("title", "Invalid IP address format");
511508
} else {
@@ -516,10 +513,7 @@ $(document).on("input blur paste", "#StaticDHCPTable td.static-ipaddr", function
516513

517514
$(document).on("input blur paste", "#StaticDHCPTable td.static-hostname", function () {
518515
const val = $(this).text().trim();
519-
// Hostnames must not contain spaces, commas, or characters invalid in DNS names
520-
const hostnameValidator =
521-
/^[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?)*$/v;
522-
if (val && !hostnameValidator.test(val)) {
516+
if (val && !utils.validateHostnameStrict(val)) {
523517
$(this).addClass("table-danger");
524518
$(this).attr("title", "Invalid hostname: only letters, digits, hyphens, and dots allowed");
525519
} else {

scripts/js/utils.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,18 @@ function validateIPv6(ip) {
263263
return validateIPv6CIDR(ipv6WithCIDR);
264264
}
265265

266+
function validateIPv6Brackets(ip) {
267+
// Check if the IPv6 is enclosed in brackets and return in case of failure
268+
if (!ip.trim().startsWith("[") || !ip.trim().endsWith("]")) {
269+
return false;
270+
}
271+
272+
// Strip brackets before validating the IPv6
273+
const ipWithoutBrackets = ip.replaceAll("[", "").replaceAll("]", "");
274+
// Validate the ip
275+
return validateIPv6(ipWithoutBrackets);
276+
}
277+
266278
function validateMAC(mac) {
267279
// Format: xx:xx:xx:xx:xx:xx where each xx is 0-9 or a-f (case insensitive)
268280
// Also allows dashes as separator, e.g. xx-xx-xx-xx-xx-xx
@@ -275,6 +287,13 @@ function validateHostname(name) {
275287
return namevalidator.test(name.trim());
276288
}
277289

290+
function validateHostnameStrict(name) {
291+
// Hostnames must not contain spaces, commas, or characters invalid in DNS names
292+
const hostnameValidator =
293+
/^[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?)*$/v;
294+
return hostnameValidator.test(name.trim());
295+
}
296+
278297
// set bootstrap-select defaults
279298
function setBsSelectDefaults() {
280299
const bsSelectDefaults = $.fn.selectpicker.Constructor.DEFAULTS;
@@ -728,11 +747,13 @@ globalThis.utils = (function () {
728747
validateIPv4,
729748
validateIPv6CIDR,
730749
validateIPv6,
750+
validateIPv6Brackets,
731751
setBsSelectDefaults,
732752
stateSaveCallback,
733753
stateLoadCallback,
734754
validateMAC,
735755
validateHostname,
756+
validateHostnameStrict,
736757
addFromQueryLog,
737758
addTD,
738759
toPercent,

0 commit comments

Comments
 (0)