fix: encode dots in URL path segments to prevent browser resolution (#3308)

When editing a regex domain that is just "." (single dot), the browser
interprets it as a relative path component ("current directory") and
resolves it away before sending the request. The server receives an
empty string, causing "Invalid request: Specify item in URI".

This happens because encodeURIComponent(".") returns "." unchanged —
dots are unreserved characters per RFC 3986. The browser only normalizes
literal "." and ".." path segments, not percent-encoded "%2E".

Add utils.encodePathSegment() which wraps encodeURIComponent and also
encodes dots to %2E, then apply it in groups-domains.js (the reported
bug) and groups.js (which was also missing encoding entirely).

Fixes #3308

Signed-off-by: Dominik <dl6er@dl6er.de>
This commit is contained in:
Dominik
2026-03-25 07:02:33 +01:00
parent 5d16e2c44a
commit cec0178e76
3 changed files with 10 additions and 2 deletions

View File

@@ -611,7 +611,7 @@ function editDomain() {
"/domains/" +
newTypestr +
"/" +
encodeURIComponent(domainDecoded),
utils.encodePathSegment(domainDecoded),
method: "put",
dataType: "json",
processData: false,

View File

@@ -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,

View File

@@ -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,