Escape a few HTML values in device details, file browser, and permission dialogs (#7823)
Wraps a handful of remaining call sites in EscapeHtml() so they match the convention already used by adjacent code in both views/default.handlebars and views/default3.handlebars. Covers the operating system attribute, volume names in the file browser, thermal sensor titles, and node/mesh names in the sharing dialog, user-group lists, and permission-removal confirmation dialogs. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
TheHermit committed
May 22, 2026 at 21:41 UTC
aee83b77809ee47e6ec2a2cbe50800244a155722
2 files changed
+20
-20
views/default.handlebars
+10
-10
@@ -4007,7 +4007,7 @@
4007
if (xxdialogTag) break;
4008
var node = getNodeFromId(message.nodeid), x = '';
4009
if (node == null) break;
4010
- x += addHtmlValue("Device", node.name);
4010
+ x += addHtmlValue("Device", EscapeHtml(node.name));
4011
x += addHtmlValue("Guest Name", message.guestname);
4012
x += addHtmlValue("User Input", message.viewOnly ? "Not allowed, view only" : "Allowed");
4013
if (message.start && message.expire) {
@@ -7817,7 +7817,7 @@
7817
//if (node.intelamt && node.intelamt.user) { x += addDeviceAttribute('Intel® AMT', node.intelamt.user); }
7818
7819
// Operating system description
7820
- if (node.osdesc) { x += addDeviceAttribute("Operating System", node.osdesc); }
7820
+ if (node.osdesc) { x += addDeviceAttribute("Operating System", EscapeHtml(node.osdesc)); }
7821
7822
// Windows Security Central
7823
if (node.wsc) {
@@ -11574,7 +11574,7 @@
11574
h += '<input file=999 style=float:left name=fd class=fcb type=checkbox onchange=p13setActions() value=\'' + f.nx + '\'> <span style=float:right title="' + title + '">' + right + '</span>';
11575
h += '<span title="' + shortname + '"><div class=fileIcon' + (f.dt == 'REMOVABLE' ? 5 : (f.dt == 'CDROM' ? 6 : f.t)) + ' onclick=p13folderset("' + encodeURIComponentEx(f.nx) + '")></div><a href=# style=cursor:pointer onclick=\'return p13folderset("' + encodeURIComponentEx(f.nx) + '")\'>';
11576
if (isWindowsNode(currentNode) && f.dt && currentNode.volumes && currentNode.volumes[shortname.charAt(0).toUpperCase()] && currentNode.volumes[shortname.charAt(0).toUpperCase()].name) {
11577
- h += currentNode.volumes[shortname.charAt(0).toUpperCase()].name + ' (' + shortname + ')';
11577
+ h += EscapeHtml(currentNode.volumes[shortname.charAt(0).toUpperCase()].name) + ' (' + shortname + ')';
11578
} else {
11579
h += shortname;
11580
}
@@ -12369,7 +12369,7 @@
12369
if (message != null) {
12370
if (Array.isArray(message.thermals) && (message.thermals.length > 0)) {
12371
var x = ' ';
12372
- for (var i in message.thermals) { x += '<div class=thermalSensor title="'+message.thermals[i].InstanceName+'">' + parseFloat(message.thermals[i].CurrentTemperature).toFixed(2) + '°C / ' + parseFloat((message.thermals[i].CurrentTemperature * 1.8) + 32).toFixed(2) + '°F' + '</div>'; }
12372
+ for (var i in message.thermals) { x += '<div class=thermalSensor title="'+EscapeHtml(message.thermals[i].InstanceName)+'">' + parseFloat(message.thermals[i].CurrentTemperature).toFixed(2) + '°C / ' + parseFloat((message.thermals[i].CurrentTemperature * 1.8) + 32).toFixed(2) + '°F' + '</div>'; }
12373
QV('extraGraphValues', true);
12374
QH('extraGraphValues', x);
12375
}
@@ -17087,7 +17087,7 @@
17087
var cr = 0, mesh = omeshes[i], r = currentUserGroup.links[mesh._id].rights, trash = '', rights = makeDeviceGroupRightsString(r);
17088
if ((userinfo.links) && (userinfo.links[mesh._id] != null) && (userinfo.links[mesh._id].rights != null)) { cr = userinfo.links[mesh._id].rights; }
17089
var meshname = '<i>' + "Unknown Device Group" + '</i>';
17090
- if (mesh) { meshname = '<a href=# onclick=\'gotoMesh("' + mesh._id + '");haltEvent(event);\'>' + mesh.name + '</a>'; } else {}
17090
+ if (mesh) { meshname = '<a href=# onclick=\'gotoMesh("' + mesh._id + '");haltEvent(event);\'>' + EscapeHtml(mesh.name) + '</a>'; } else {}
17091
if ((cr & 2) != 0) {
17092
trash = '<a href=# onclick=\'return p51removeMeshFromUserGroup(event,"' + encodeURIComponentEx(mesh._id) + '")\' title="' + "Remove user group rights to this device group" + '" style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>';
17093
rights = '<span style=cursor:pointer onclick=p20showAddMeshUserDialog(3,"' + encodeURIComponentEx(mesh._id) + '")>' + rights + ' <img class=hoverButton style=cursor:pointer src=images/link5.png></span>';
@@ -17110,7 +17110,7 @@
17110
for (var i in onodes) {
17111
var node = onodes[i], r = currentUserGroup.links[node._id].rights, trash = '', rights = makeUserDeviceRightsString(r), cr = GetNodeRights(node);
17112
var nodename = '<i>' + "Unknown Device" + '</i>';
17113
- if (node) { nodename = '<a href=# onclick=\'gotoDevice("' + node._id + '");haltEvent(event);\'>' + node.name + '</a>'; } else {}
17113
+ if (node) { nodename = '<a href=# onclick=\'gotoDevice("' + node._id + '");haltEvent(event);\'>' + EscapeHtml(node.name) + '</a>'; } else {}
17114
if ((cr & 2) != 0) {
17115
trash = '<a href=# onclick=\'return p51removeDeviceFromUserGroup(event,"' + encodeURIComponentEx(node._id) + '")\' title="' + "Remove user group rights to this device" + '" style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>';
17116
rights = '<span style=cursor:pointer onclick=p20showAddMeshUserDialog(7,"' + encodeURIComponentEx(node._id) + '")>' + rights + ' <img class=hoverButton style=cursor:pointer src=images/link5.png></span>';
@@ -17158,7 +17158,7 @@
17158
if (xxdialogMode) return;
17159
var node = getNodeFromId(decodeURIComponent(nodeid));
17160
if (node == null) return;
17161
- setDialogMode(2, "Remove Device Permissions", 3, p51removeDeviceFromUserGroupEx, format("Confirm removal of access rights for device \"{0}\"?", node.name), node._id);
17161
+ setDialogMode(2, "Remove Device Permissions", 3, p51removeDeviceFromUserGroupEx, format("Confirm removal of access rights for device \"{0}\"?", EscapeHtml(node.name)), node._id);
17162
}
17163
17164
function p51removeDeviceFromUserGroupEx(b, nodeid) {
@@ -17169,7 +17169,7 @@
17169
if (xxdialogMode) return;
17170
var mesh = meshes[decodeURIComponent(meshid)];
17171
if (mesh == null) return;
17172
- setDialogMode(2, "Remove Device Group Permissions", 3, p51removeMeshFromUserGroupEx, format("Confirm removal of access rights for device group \"{0}\"?", mesh.name), mesh._id);
17172
+ setDialogMode(2, "Remove Device Group Permissions", 3, p51removeMeshFromUserGroupEx, format("Confirm removal of access rights for device group \"{0}\"?", EscapeHtml(mesh.name)), mesh._id);
17173
}
17174
17175
function p51removeMeshFromUserGroupEx(b, meshid) {
@@ -17865,7 +17865,7 @@
17865
function p30removeNodeFromUser(event, nodeid) {
17866
if (xxdialogMode) return;
17867
var node = getNodeFromId(decodeURIComponent(nodeid));
17868
- setDialogMode(2, "Remove Device Permissions", 3, function(b, node) { meshserver.send({ action: 'adddeviceuser', nodeid: node._id, nodename: node.name, userids: [ currentUser._id ], rights: 0, remove: true }); }, format("Confirm removal of access rights for device \"{0}\"?", node.name), node);
17868
+ setDialogMode(2, "Remove Device Permissions", 3, function(b, node) { meshserver.send({ action: 'adddeviceuser', nodeid: node._id, nodename: node.name, userids: [ currentUser._id ], rights: 0, remove: true }); }, format("Confirm removal of access rights for device \"{0}\"?", EscapeHtml(node.name)), node);
17869
}
17870
17871
function p30removeUserFromNode(event, userid) {
@@ -17913,7 +17913,7 @@
17913
if (xxdialogMode) return;
17914
var mesh = meshes[decodeURIComponent(meshid)];
17915
if (mesh == null) return;
17916
- setDialogMode(2, "Remove Device Group Permissions", 3, p30removeMeshFromUserEx, format("Confirm removal of access rights for device group \"{0}\"?", mesh.name), mesh._id);
17916
+ setDialogMode(2, "Remove Device Group Permissions", 3, p30removeMeshFromUserEx, format("Confirm removal of access rights for device group \"{0}\"?", EscapeHtml(mesh.name)), mesh._id);
17917
}
17918
17919
function p30removeMeshFromUserEx(b, meshid) {
views/default3.handlebars
+10
-10
@@ -4692,7 +4692,7 @@
4692
case 'createDeviceShareLink': { // Guest sharing link
4693
var node = getNodeFromId(message.nodeid), x = '';
4694
if (node == null) break;
4695
- x += addHtmlValue("Device", node.name);
4695
+ x += addHtmlValue("Device", EscapeHtml(node.name));
4696
x += addHtmlValue("Guest Name", message.guestname);
4697
x += addHtmlValue("User Input", message.viewOnly ? "Not allowed, view only" : "Allowed");
4698
if (message.start && message.expire) {
@@ -8710,7 +8710,7 @@
8710
//if (node.intelamt && node.intelamt.user) { x += addDeviceAttribute('Intel® AMT', node.intelamt.user); }
8711
8712
// Operating system description
8713
- if (node.osdesc) { x += addDeviceAttribute("Operating System", node.osdesc); }
8713
+ if (node.osdesc) { x += addDeviceAttribute("Operating System", EscapeHtml(node.osdesc)); }
8714
8715
// Windows Security Central
8716
if (node.wsc) {
@@ -12609,7 +12609,7 @@
12609
h += '<input file=999 style=float:left name=fd class=fcb type=checkbox class="form-check-input me-2" onchange=p13setActions() value=\'' + f.nx + '\'> <span style=float:right title="' + title + '">' + right + '</span>';
12610
h += '<span title="' + shortname + '"><div class=fileIcon' + (f.dt == 'REMOVABLE' ? 5 : (f.dt == 'CDROM' ? 6 : f.t)) + ' onclick=p13folderset("' + encodeURIComponentEx(f.nx) + '")></div><a href=# style=cursor:pointer onclick=\'return p13folderset("' + encodeURIComponentEx(f.nx) + '")\'>';
12611
if (isWindowsNode(currentNode) && f.dt && currentNode.volumes && currentNode.volumes[shortname.charAt(0).toUpperCase()] && currentNode.volumes[shortname.charAt(0).toUpperCase()].name) {
12612
- h += currentNode.volumes[shortname.charAt(0).toUpperCase()].name + ' (' + shortname + ')';
12612
+ h += EscapeHtml(currentNode.volumes[shortname.charAt(0).toUpperCase()].name) + ' (' + shortname + ')';
12613
} else {
12614
h += shortname;
12615
}
@@ -13499,7 +13499,7 @@
13499
if (message != null) {
13500
if (Array.isArray(message.thermals) && (message.thermals.length > 0)) {
13501
var x = ' ';
13502
- for (var i in message.thermals) { x += '<div class=thermalSensor title="' + message.thermals[i].InstanceName + '">' + parseFloat(message.thermals[i].CurrentTemperature).toFixed(2) + '°C / ' + parseFloat((message.thermals[i].CurrentTemperature * 1.8) + 32).toFixed(2) + '°F' + '</div>'; }
13502
+ for (var i in message.thermals) { x += '<div class=thermalSensor title="' + EscapeHtml(message.thermals[i].InstanceName) + '">' + parseFloat(message.thermals[i].CurrentTemperature).toFixed(2) + '°C / ' + parseFloat((message.thermals[i].CurrentTemperature * 1.8) + 32).toFixed(2) + '°F' + '</div>'; }
13503
QV('extraGraphValues', true);
13504
QH('extraGraphValues', x);
13505
}
@@ -18599,7 +18599,7 @@
18599
var cr = 0, mesh = omeshes[i], r = currentUserGroup.links[mesh._id].rights, trash = '', rights = makeDeviceGroupRightsString(r);
18600
if ((userinfo.links) && (userinfo.links[mesh._id] != null) && (userinfo.links[mesh._id].rights != null)) { cr = userinfo.links[mesh._id].rights; }
18601
var meshname = '<i>' + "Unknown Device Group" + '</i>';
18602
- if (mesh) { meshname = '<a href=# onclick=\'gotoMesh("' + mesh._id + '");haltEvent(event);\'>' + mesh.name + '</a>'; } else { }
18602
+ if (mesh) { meshname = '<a href=# onclick=\'gotoMesh("' + mesh._id + '");haltEvent(event);\'>' + EscapeHtml(mesh.name) + '</a>'; } else { }
18603
if ((cr & 2) != 0) {
18604
trash = '<a href=# onclick=\'return p51removeMeshFromUserGroup(event,"' + encodeURIComponentEx(mesh._id) + '")\' title="' + "Remove user group rights to this device group" + '" style=cursor:pointer><i class="fa-solid fa-trash text-danger hoverButton"></i></a>';
18605
rights = '<span style=cursor:pointer onclick=p20showAddMeshUserDialog(3,"' + encodeURIComponentEx(mesh._id) + '")>' + rights + ' <img class=hoverButton style=cursor:pointer src=images/link5.png></span>';
@@ -18622,7 +18622,7 @@
18622
for (var i in onodes) {
18623
var node = onodes[i], r = currentUserGroup.links[node._id].rights, trash = '', rights = makeUserDeviceRightsString(r), cr = GetNodeRights(node);
18624
var nodename = '<i>' + "Unknown Device" + '</i>';
18625
- if (node) { nodename = '<a href=# onclick=\'gotoDevice("' + node._id + '");haltEvent(event);\'>' + node.name + '</a>'; } else { }
18625
+ if (node) { nodename = '<a href=# onclick=\'gotoDevice("' + node._id + '");haltEvent(event);\'>' + EscapeHtml(node.name) + '</a>'; } else { }
18626
if ((cr & 2) != 0) {
18627
trash = '<a href=# onclick=\'return p51removeDeviceFromUserGroup(event,"' + encodeURIComponentEx(node._id) + '")\' title="' + "Remove user group rights to this device" + '" style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>';
18628
rights = '<span style=cursor:pointer onclick=p20showAddMeshUserDialog(7,"' + encodeURIComponentEx(node._id) + '")>' + rights + ' <img class=hoverButton style=cursor:pointer src=images/link5.png></span>';
@@ -18672,7 +18672,7 @@
18672
if (xxdialogMode) return;
18673
var node = getNodeFromId(decodeURIComponent(nodeid));
18674
if (node == null) return;
18675
- setModalContent('xxAddAgent', "Remove Device Permissions", format("Confirm removal of access rights for device \"{0}\"?", node.name));
18675
+ setModalContent('xxAddAgent', "Remove Device Permissions", format("Confirm removal of access rights for device \"{0}\"?", EscapeHtml(node.name)));
18676
showModal('xxAddAgentModal', 'idx_dlgOkButton', () => p51removeDeviceFromUserGroupEx(3, node._id));
18677
}
18678
@@ -18684,7 +18684,7 @@
18684
if (xxdialogMode) return;
18685
var mesh = meshes[decodeURIComponent(meshid)];
18686
if (mesh == null) return;
18687
- setModalContent('xxAddAgent', "Remove Device Group Permissions", format("Confirm removal of access rights for device group \"{0}\"?", mesh.name));
18687
+ setModalContent('xxAddAgent', "Remove Device Group Permissions", format("Confirm removal of access rights for device group \"{0}\"?", EscapeHtml(mesh.name)));
18688
showModal('xxAddAgentModal', 'idx_dlgOkButton', () => { meshserver.send({ action: 'removemeshuser', meshid: decodeURIComponent(meshid), userid: currentUserGroup._id }); });;
18689
}
18690
function p51editgroup(focus, nameReadOnly) {
@@ -19410,7 +19410,7 @@
19410
function p30removeNodeFromUser(event, nodeid) {
19411
if (xxdialogMode) return;
19412
var node = getNodeFromId(decodeURIComponent(nodeid));
19413
- setModalContent('xxAddAgent', "Remove Device Permissions", format("Confirm removal of access rights for device \"{0}\"?", node.name));
19413
+ setModalContent('xxAddAgent', "Remove Device Permissions", format("Confirm removal of access rights for device \"{0}\"?", EscapeHtml(node.name)));
19414
showModal('xxAddAgentModal', 'idx_dlgOkButton', function (b, node) { meshserver.send({ action: 'adddeviceuser', nodeid: node._id, nodename: node.name, userids: [currentUser._id], rights: 0, remove: true }); }, 3, node);
19415
}
19416
@@ -19471,7 +19471,7 @@
19471
var mesh = meshes[decodeURIComponent(meshid)];
19472
if (mesh == null) return;
19473
19474
- setModalContent('xxAddAgent', "Remove Device Group Permissions", format("Confirm removal of access rights for device group \"{0}\"?", mesh.name));
19474
+ setModalContent('xxAddAgent', "Remove Device Group Permissions", format("Confirm removal of access rights for device group \"{0}\"?", EscapeHtml(mesh.name)));
19475
showModal('xxAddAgentModal', 'idx_dlgOkButton', function () {
19476
p30removeMeshFromUserEx(3, mesh._id);
19477
});