From 714b49e4e753c0c5d37d73536164bd1059d58ae9 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 18 Aug 2026 21:55:06 +0300 Subject: [PATCH] security(compliance-hub): HTML-encode the application name in the export-history action cell The export/purge history model builds each row's action cell as an HTML string and the template renders it with v-html. Every other value in that string comes from the API, which HTML-encodes its output, but the application name is read from countlyGlobal, whose values are raw at runtime. Encode the application name with countlyCommon.encodeHtml so it is rendered as text, matching the encoding of the other fields in the same string. Only the application name needed encoding; the remaining fields are already API-encoded and must not be encoded again. The display is unchanged. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 1 + .../frontend/public/javascripts/countly.models.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37ace8a79ae..ec8ca0f7326 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Enterprise Fixes: - [data-manager] Fixed editing an event whose key contains `&` creating undeletable duplicate rows in the events table Security Fixes: +- [compliance-hub] The export/purge history table now HTML-encodes the application name before it is placed in the action cell, so an application name is shown as text rather than markup - [hooks] Internal event hooks are now scoped to the apps the hook belongs to: app creation is a global-admin-only event, and remote-config, cohort, alert and hook-chaining events are only delivered when the event's app is one the hook is scoped to - [compliance-hub] The consents table now returns a fixed set of fields; a projection supplied on the request is no longer used to widen the response beyond the consent columns - [dashboards] Widgets are no longer copied when the copying user has no access to the apps they reference, and widget app ids are validated on widget create and update diff --git a/plugins/compliance-hub/frontend/public/javascripts/countly.models.js b/plugins/compliance-hub/frontend/public/javascripts/countly.models.js index bd758822308..7ba4100c071 100644 --- a/plugins/compliance-hub/frontend/public/javascripts/countly.models.js +++ b/plugins/compliance-hub/frontend/public/javascripts/countly.models.js @@ -194,7 +194,7 @@ var ret = "

" + ((jQuery.i18n.map["systemlogs.action." + row.a]) ? jQuery.i18n.map["systemlogs.action." + row.a] : row.a) + "

"; if (typeof row.i === "object") { if (typeof row.i.app_id !== "undefined" && countlyGlobal.apps[row.i.app_id]) { - ret += "

" + jQuery.i18n.map["systemlogs.for-app"] + ": " + countlyGlobal.apps[row.i.app_id].name + "

"; + ret += "

" + jQuery.i18n.map["systemlogs.for-app"] + ": " + countlyCommon.encodeHtml(countlyGlobal.apps[row.i.app_id].name) + "

"; } if (typeof row.i.appuser_id !== "undefined") { ret += "

" + jQuery.i18n.map["systemlogs.for-appuser"] + ": " + row.i.appuser_id + "

";