shieldx/dashboard/src/ShieldXDashboard.tsx
Rene Fichtmueller 1c4c034483 feat: ShieldX v0.3.0 — UnicodeScanner (L5), DNS Covert Channel rules, ATLAS v5.4 mappings
- Layer 4 EntropyScanner: Shannon entropy, Base32/Base64 detection, CVE-2025-55284
  ping/nslookup exfil, EchoLeak markdown pattern, DNS tunneling (iodine/dnscat)
- Layer 5 UnicodeScanner: ASCII Smuggling (U+E0000 Tags Block), Variant Selectors,
  Zero-Width steganography, CamoLeak image-ordering (CVE-2025-53773), homoglyphs,
  BiDi override, high-entropy URL params
- 30 DNS covert channel rules (dns-001 to dns-030)
- ATLASMapper: 29 techniques (ATLAS v5.4.0 Feb 2026), added AML.T0062 (Agent Tool
  Invocation), AML.TA0015 (C2 tactic), memory poisoning, multi-agent trust,
  CamoLeak, Unicode steganography mappings
- Rule count: 72 → 102
- Build: tsup 316ms, zero TypeScript errors
2026-03-31 16:32:16 +02:00

136 lines
4.4 KiB
TypeScript

'use client'
import { theme } from './theme'
import { Tabs } from './components/Tabs'
import type { TabItem } from './components/Tabs'
import { useShieldX } from './hooks'
import { DashboardHome } from './pages/DashboardHome'
import { KillChainView } from './pages/KillChainView'
import { IncidentFeed } from './pages/IncidentFeed'
import { LearningDashboard } from './pages/LearningDashboard'
import { AttackGraphViewer } from './pages/AttackGraphViewer'
import { BehavioralMonitor } from './pages/BehavioralMonitor'
import { ComplianceCenter } from './pages/ComplianceCenter'
import { HealingLog } from './pages/HealingLog'
import { ReviewQueue } from './pages/ReviewQueue'
import { ConfigPanel } from './pages/ConfigPanel'
import { ProtectedLLMs } from './pages/ProtectedLLMs'
export interface ShieldXDashboardProps {
readonly defaultTab?: string
readonly className?: string
}
const TABS: readonly TabItem[] = [
{ key: 'overview', label: 'Overview', content: () => <DashboardHome /> },
{ key: 'killchain', label: 'Kill Chain', content: () => <KillChainView /> },
{ key: 'incidents', label: 'Incidents', content: () => <IncidentFeed /> },
{ key: 'learning', label: 'Learning', content: () => <LearningDashboard /> },
{ key: 'attackgraph', label: 'Attack Graph', content: () => <AttackGraphViewer /> },
{ key: 'behavioral', label: 'Behavioral', content: () => <BehavioralMonitor /> },
{ key: 'compliance', label: 'Compliance', content: () => <ComplianceCenter /> },
{ key: 'healing', label: 'Healing', content: () => <HealingLog /> },
{ key: 'review', label: 'Review', content: () => <ReviewQueue /> },
{ key: 'config', label: 'Config', content: () => <ConfigPanel /> },
{ key: 'endpoints', label: 'Protected LLMs', content: () => <ProtectedLLMs /> },
]
export function ShieldXDashboard({ defaultTab, className }: ShieldXDashboardProps) {
const { error } = useShieldX()
return (
<div
className={className}
style={{
background: theme.colors.bg,
color: theme.colors.text,
fontFamily: theme.font,
minHeight: 400,
borderRadius: 8,
overflow: 'hidden',
}}
>
{/* Header */}
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
padding: '16px 24px',
borderBottom: `1px solid ${theme.colors.card}`,
background: 'rgba(15, 23, 42, 0.95)',
}}
>
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
<div
style={{
width: 28,
height: 28,
borderRadius: 6,
background: `linear-gradient(135deg, ${theme.colors.accent}, #6366f1)`,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: 14,
fontWeight: 800,
color: '#fff',
}}
>
SX
</div>
<div>
<div style={{ fontSize: 15, fontWeight: 700, color: theme.colors.textBright, letterSpacing: '-0.01em' }}>
ShieldX
</div>
<div style={{ fontSize: 10, color: theme.colors.textDim, textTransform: 'uppercase', letterSpacing: '0.06em' }}>
LLM Defense Dashboard
</div>
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
<div
style={{
width: 8,
height: 8,
borderRadius: '50%',
background: theme.colors.threatNone,
animation: 'shieldx-pulse 2s infinite',
}}
/>
<span style={{ fontSize: 11, color: theme.colors.textDim }}>Live</span>
</div>
</div>
{/* Error bar */}
{error ? (
<div
style={{
background: 'rgba(239, 68, 68, 0.1)',
border: '1px solid rgba(239, 68, 68, 0.3)',
borderRadius: 6,
padding: '12px 16px',
margin: 24,
color: theme.colors.threatCritical,
fontSize: 13,
}}
>
{error}
</div>
) : null}
{/* Content */}
<div style={{ padding: 24 }}>
<Tabs tabs={TABS} defaultTab={defaultTab ?? 'overview'} />
</div>
<style>{`
@keyframes shieldx-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
`}</style>
</div>
)
}