From 4cf3e9f50bb79a3d04f6cd2384c21e4a22d2261c Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Wed, 14 Jan 2026 04:56:25 +0000
Subject: [PATCH] fix(security): allow trusted html in info panel while
sanitizing user input
- Add `isHtml` flag to `Focus Node` button to bypass escaping
- Update `UIManager` to check for `isHtml` flag before formatting/escaping
- Add regression tests for trusted HTML rendering logic
---
src/info-panel/UIManager.ts | 5 +++--
tests/unit/Security.test.ts | 29 +++++++++++++++++++++++++++++
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/src/info-panel/UIManager.ts b/src/info-panel/UIManager.ts
index dbe0af2..b887f83 100644
--- a/src/info-panel/UIManager.ts
+++ b/src/info-panel/UIManager.ts
@@ -776,7 +776,8 @@ export class UIManager {
label: 'Location',
value: `${Icons.focus} Focus Node`,
clickable: 'zoom',
- nodeId: info.hoveredNode.id
+ nodeId: info.hoveredNode.id,
+ isHtml: true
});
// Add category if available
@@ -883,7 +884,7 @@ export class UIManager {
${section.content.map((item: any) => {
- const value = formatValue(item.value, item.label);
+ const value = item.isHtml ? item.value : formatValue(item.value, item.label);
const valueClass = getValueClass(item.value);
const valueAttributes = getValueAttributes(item.value);
const clickableAttr = item.clickable ? `data-clickable="${item.clickable}"` : '';
diff --git a/tests/unit/Security.test.ts b/tests/unit/Security.test.ts
index ad3f258..c4cb5fe 100644
--- a/tests/unit/Security.test.ts
+++ b/tests/unit/Security.test.ts
@@ -22,4 +22,33 @@ describe('Security', () => {
expect(escaped).toContain(''single quotes'');
});
});
+
+ describe('UIManager Rendering Logic', () => {
+ // Mock logic for UIManager rendering to verify the fix for trusted HTML
+ it('should NOT escape values marked as isHtml', () => {
+ const item = {
+ value: 'Icon Button',
+ isHtml: true,
+ label: 'Test Button'
+ };
+
+ const renderedValue = item.isHtml ? item.value : formatValue(item.value, item.label);
+
+ expect(renderedValue).toContain('');
+ expect(renderedValue).not.toContain('<span class="icon">');
+ });
+
+ it('should escape values NOT marked as isHtml', () => {
+ const item = {
+ value: '',
+ isHtml: false, // or undefined
+ label: 'Malicious Input'
+ };
+
+ const renderedValue = item.isHtml ? item.value : formatValue(item.value, item.label);
+
+ expect(renderedValue).not.toContain('