From c282f74bd4d48f58182cfaf3625048bd6f8c96a0 Mon Sep 17 00:00:00 2001 From: anti Date: Fri, 24 Apr 2026 00:51:31 -0400 Subject: [PATCH] fix(web/dashboard): wrap long kv-chips instead of blowing out the EVENT column Key:value chips in the live-feed event cell used the default .chip style, which is white-space: nowrap + inline-flex. A long cmd: value (attacker-controlled shell strings, URLs, base64 payloads) stretched the chip horizontally past the column, pushing the whole table into horizontal scroll and clipping subsequent columns off-screen. Add a chip-kv variant that allows the value to wrap inside a max-width: 100% chip (word-break: break-word, overflow-wrap: anywhere for dense strings with no natural break). The key-label stays on the first line via flex-shrink: 0. Short values (uid: 0, user: root) stay tight; long ones wrap onto multiple lines inside the chip. Also set minWidth: 0 on the EVENT td + nested flex containers so flex children honour the column width instead of growing to fit content. Added title={k: v} on each chip for full-value hover in case the wrap is still clipped. --- decnet_web/src/components/Dashboard.css | 16 +++++++++++++++ decnet_web/src/components/Dashboard.tsx | 26 ++++++++++++++++--------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/decnet_web/src/components/Dashboard.css b/decnet_web/src/components/Dashboard.css index aea8c118..0965d2e5 100644 --- a/decnet_web/src/components/Dashboard.css +++ b/decnet_web/src/components/Dashboard.css @@ -71,6 +71,22 @@ background: rgba(255, 65, 65, 0.1); } +/* Key-value chips in the live-feed event column. Values are unbounded + (attacker-supplied command strings, URLs, base64 payloads), so these + must wrap inside the chip rather than inherit the default nowrap — + otherwise a single `cmd: echo <2KB>` blows out the table width. */ +.chip.chip-kv { + white-space: normal; + word-break: break-word; + overflow-wrap: anywhere; + max-width: 100%; + align-items: flex-start; + line-height: 1.35; +} +.chip.chip-kv > .dim { + flex-shrink: 0; +} + /* Breach banner */ .breach-banner { background: rgba(255, 65, 65, 0.1); diff --git a/decnet_web/src/components/Dashboard.tsx b/decnet_web/src/components/Dashboard.tsx index 007eb0bd..21f71d17 100644 --- a/decnet_web/src/components/Dashboard.tsx +++ b/decnet_web/src/components/Dashboard.tsx @@ -359,8 +359,8 @@ const Dashboard: React.FC = ({ searchQuery }) => { {log.decky} {log.service} {log.attacker_ip} - -
+ +
{(() => { const et = log.event_type && log.event_type !== '-' ? log.event_type : null; @@ -378,7 +378,7 @@ const Dashboard: React.FC = ({ searchQuery }) => { })()}
{Object.keys(parsedFields).length > 0 && ( -
+
{parsedFields.stored_as != null && (
)}