diff --git a/scripts/js/groups-domains.js b/scripts/js/groups-domains.js index 23adc919..4af046cb 100644 --- a/scripts/js/groups-domains.js +++ b/scripts/js/groups-domains.js @@ -611,7 +611,7 @@ function editDomain() { "/domains/" + newTypestr + "/" + - encodeURIComponent(domainDecoded), + utils.encodePathSegment(domainDecoded), method: "put", dataType: "json", processData: false, diff --git a/scripts/js/groups.js b/scripts/js/groups.js index fbad0364..4452466a 100644 --- a/scripts/js/groups.js +++ b/scripts/js/groups.js @@ -328,7 +328,7 @@ function editGroup() { utils.disableAll(); utils.showAlert("info", "", "Editing group...", oldName); $.ajax({ - url: document.body.dataset.apiurl + "/groups/" + oldName, + url: document.body.dataset.apiurl + "/groups/" + utils.encodePathSegment(oldName), method: "put", dataType: "json", processData: false, diff --git a/scripts/js/utils.js b/scripts/js/utils.js index 2ab9edcb..b6554629 100644 --- a/scripts/js/utils.js +++ b/scripts/js/utils.js @@ -518,6 +518,13 @@ function parseQueryString() { return Object.fromEntries(params.entries()); } +// Encode a string for use as a URL path segment. encodeURIComponent does not +// encode dots, but browsers resolve "." and ".." as relative path components +// before sending the request, breaking domains like "." or "..". +function encodePathSegment(text) { + return encodeURIComponent(text).replaceAll(".", "%2E"); +} + function hexEncode(text) { if (typeof text !== "string" || text.length === 0) return ""; @@ -726,6 +733,7 @@ globalThis.utils = (function () { changeTableButtonStates, getCSSval, parseQueryString, + encodePathSegment, hexEncode, hexDecode, listsAlert,