@threatcaptain/tc-reports 0.2.14 → 0.2.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +528 -88
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +529 -89
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import * as React from "react";
|
|
|
3
3
|
import React__default, { forwardRef, createElement, createContext, useContext, useRef, useState, useCallback, useEffect, useImperativeHandle, useMemo, cloneElement, useLayoutEffect, PureComponent, isValidElement, Children, Component } from "react";
|
|
4
4
|
import * as ReactDOM from "react-dom";
|
|
5
5
|
import ReactDOM__default from "react-dom";
|
|
6
|
-
import { FileText, AlertTriangle, Shield, DollarSign, CheckCircle, Target, BarChart3, Building2 } from "lucide-react";
|
|
6
|
+
import { FileText, AlertTriangle, Shield, DollarSign, X as X$2, CheckCircle, Target, BarChart3, Building2 } from "lucide-react";
|
|
7
7
|
import { useNavigate, useSearchParams } from "react-router-dom";
|
|
8
8
|
function createContext2(rootComponentName, defaultContext) {
|
|
9
9
|
const Context = React.createContext(defaultContext);
|
|
@@ -51136,8 +51136,8 @@ var RadarChart = generateCategoricalChart({
|
|
|
51136
51136
|
});
|
|
51137
51137
|
const ATTACK_STEPS = [
|
|
51138
51138
|
{
|
|
51139
|
-
|
|
51140
|
-
|
|
51139
|
+
stepId: "get-in",
|
|
51140
|
+
stepName: "Step 1: Get In",
|
|
51141
51141
|
description: "Initial access and reconnaissance phase",
|
|
51142
51142
|
tactics: [
|
|
51143
51143
|
"Reconnaissance",
|
|
@@ -51149,24 +51149,24 @@ const ATTACK_STEPS = [
|
|
|
51149
51149
|
// red
|
|
51150
51150
|
},
|
|
51151
51151
|
{
|
|
51152
|
-
|
|
51153
|
-
|
|
51152
|
+
stepId: "sneak-around",
|
|
51153
|
+
stepName: "Step 2: Sneak Around",
|
|
51154
51154
|
description: "Discovery and movement within the network",
|
|
51155
51155
|
tactics: ["Discovery", "Lateral Movement", "Defense Evasion"],
|
|
51156
51156
|
color: "#f59e0b"
|
|
51157
51157
|
// amber
|
|
51158
51158
|
},
|
|
51159
51159
|
{
|
|
51160
|
-
|
|
51161
|
-
|
|
51160
|
+
stepId: "take-control",
|
|
51161
|
+
stepName: "Step 3: Take Control",
|
|
51162
51162
|
description: "Establishing persistence and escalating privileges",
|
|
51163
51163
|
tactics: ["Privilege Escalation", "Persistence", "Credential Access"],
|
|
51164
51164
|
color: "#8b5cf6"
|
|
51165
51165
|
// violet
|
|
51166
51166
|
},
|
|
51167
51167
|
{
|
|
51168
|
-
|
|
51169
|
-
|
|
51168
|
+
stepId: "stay-hidden",
|
|
51169
|
+
stepName: "Step 4: Stay Hidden",
|
|
51170
51170
|
description: "Maintaining access and achieving objectives",
|
|
51171
51171
|
tactics: ["Command and Control", "Collection", "Exfiltration", "Impact"],
|
|
51172
51172
|
color: "#06b6d4"
|
|
@@ -51342,9 +51342,501 @@ const MitreAttack = ({ breachData, overallLikelihood }) => {
|
|
|
51342
51342
|
] })
|
|
51343
51343
|
] });
|
|
51344
51344
|
};
|
|
51345
|
+
const CIS_MITRE_MAPPING = {
|
|
51346
|
+
1: {
|
|
51347
|
+
controlName: "Inventory & Control of Enterprise Assets",
|
|
51348
|
+
mitrePhases: [
|
|
51349
|
+
"Reconnaissance",
|
|
51350
|
+
"Initial Access",
|
|
51351
|
+
"Defense Evasion",
|
|
51352
|
+
"Discovery"
|
|
51353
|
+
],
|
|
51354
|
+
impactReduction: 15,
|
|
51355
|
+
// 15% reduction in breach cost
|
|
51356
|
+
implementationCost: 25e3,
|
|
51357
|
+
description: "Asset visibility prevents unknown attack vectors and reconnaissance"
|
|
51358
|
+
},
|
|
51359
|
+
2: {
|
|
51360
|
+
controlName: "Inventory & Control of Software Assets",
|
|
51361
|
+
mitrePhases: ["Initial Access", "Execution", "Persistence", "Discovery"],
|
|
51362
|
+
impactReduction: 18,
|
|
51363
|
+
implementationCost: 3e4,
|
|
51364
|
+
description: "Software control blocks malicious applications"
|
|
51365
|
+
},
|
|
51366
|
+
3: {
|
|
51367
|
+
controlName: "Data Protection",
|
|
51368
|
+
mitrePhases: ["Collection", "Exfiltration"],
|
|
51369
|
+
impactReduction: 35,
|
|
51370
|
+
implementationCost: 5e4,
|
|
51371
|
+
description: "Encryption dramatically reduces data breach impact"
|
|
51372
|
+
},
|
|
51373
|
+
4: {
|
|
51374
|
+
controlName: "Secure Configuration of Enterprise Assets & Software",
|
|
51375
|
+
mitrePhases: ["Initial Access", "Privilege Escalation", "Defense Evasion"],
|
|
51376
|
+
impactReduction: 22,
|
|
51377
|
+
implementationCost: 4e4,
|
|
51378
|
+
description: "Hardening prevents exploitation of misconfigurations"
|
|
51379
|
+
},
|
|
51380
|
+
5: {
|
|
51381
|
+
controlName: "Account Management",
|
|
51382
|
+
mitrePhases: [
|
|
51383
|
+
"Initial Access",
|
|
51384
|
+
"Privilege Escalation",
|
|
51385
|
+
"Persistence",
|
|
51386
|
+
"Credential Access"
|
|
51387
|
+
],
|
|
51388
|
+
impactReduction: 28,
|
|
51389
|
+
implementationCost: 35e3,
|
|
51390
|
+
description: "Proper account controls limit attacker access"
|
|
51391
|
+
},
|
|
51392
|
+
6: {
|
|
51393
|
+
controlName: "Access Control Management",
|
|
51394
|
+
mitrePhases: [
|
|
51395
|
+
"Initial Access",
|
|
51396
|
+
"Privilege Escalation",
|
|
51397
|
+
"Lateral Movement",
|
|
51398
|
+
"Credential Access"
|
|
51399
|
+
],
|
|
51400
|
+
impactReduction: 30,
|
|
51401
|
+
implementationCost: 45e3,
|
|
51402
|
+
description: "MFA and access controls significantly reduce breach success"
|
|
51403
|
+
},
|
|
51404
|
+
7: {
|
|
51405
|
+
controlName: "Continuous Vulnerability Management",
|
|
51406
|
+
mitrePhases: [
|
|
51407
|
+
"Resource Development",
|
|
51408
|
+
"Initial Access",
|
|
51409
|
+
"Privilege Escalation",
|
|
51410
|
+
"Defense Evasion",
|
|
51411
|
+
"Discovery"
|
|
51412
|
+
],
|
|
51413
|
+
impactReduction: 25,
|
|
51414
|
+
implementationCost: 6e4,
|
|
51415
|
+
description: "Patching closes known attack vectors and limits resource development"
|
|
51416
|
+
},
|
|
51417
|
+
8: {
|
|
51418
|
+
controlName: "Audit Log Management",
|
|
51419
|
+
mitrePhases: ["Defense Evasion", "Collection", "Discovery"],
|
|
51420
|
+
impactReduction: 20,
|
|
51421
|
+
implementationCost: 55e3,
|
|
51422
|
+
description: "Logging enables faster detection and response"
|
|
51423
|
+
},
|
|
51424
|
+
9: {
|
|
51425
|
+
controlName: "Email & Web Browser Protections",
|
|
51426
|
+
mitrePhases: [
|
|
51427
|
+
"Resource Development",
|
|
51428
|
+
"Initial Access",
|
|
51429
|
+
"Command and Control"
|
|
51430
|
+
],
|
|
51431
|
+
impactReduction: 32,
|
|
51432
|
+
implementationCost: 25e3,
|
|
51433
|
+
description: "Blocks most common attack vectors and resource development"
|
|
51434
|
+
},
|
|
51435
|
+
10: {
|
|
51436
|
+
controlName: "Malware Defenses",
|
|
51437
|
+
mitrePhases: ["Initial Access", "Execution", "Defense Evasion"],
|
|
51438
|
+
impactReduction: 28,
|
|
51439
|
+
implementationCost: 4e4,
|
|
51440
|
+
description: "EDR prevents malware execution and lateral movement"
|
|
51441
|
+
},
|
|
51442
|
+
11: {
|
|
51443
|
+
controlName: "Data Recovery",
|
|
51444
|
+
mitrePhases: ["Impact"],
|
|
51445
|
+
impactReduction: 45,
|
|
51446
|
+
implementationCost: 35e3,
|
|
51447
|
+
description: "Backups dramatically reduce ransomware impact"
|
|
51448
|
+
},
|
|
51449
|
+
12: {
|
|
51450
|
+
controlName: "Network Infrastructure Management",
|
|
51451
|
+
mitrePhases: [
|
|
51452
|
+
"Initial Access",
|
|
51453
|
+
"Lateral Movement",
|
|
51454
|
+
"Command and Control",
|
|
51455
|
+
"Discovery"
|
|
51456
|
+
],
|
|
51457
|
+
impactReduction: 18,
|
|
51458
|
+
implementationCost: 5e4,
|
|
51459
|
+
description: "Network segmentation limits breach scope"
|
|
51460
|
+
},
|
|
51461
|
+
13: {
|
|
51462
|
+
controlName: "Network Monitoring & Defense",
|
|
51463
|
+
mitrePhases: [
|
|
51464
|
+
"Reconnaissance",
|
|
51465
|
+
"Initial Access",
|
|
51466
|
+
"Lateral Movement",
|
|
51467
|
+
"Command and Control",
|
|
51468
|
+
"Exfiltration",
|
|
51469
|
+
"Discovery"
|
|
51470
|
+
],
|
|
51471
|
+
impactReduction: 25,
|
|
51472
|
+
implementationCost: 7e4,
|
|
51473
|
+
description: "Network detection identifies threats early including reconnaissance"
|
|
51474
|
+
},
|
|
51475
|
+
14: {
|
|
51476
|
+
controlName: "Security Awareness & Skills Training",
|
|
51477
|
+
mitrePhases: ["Initial Access", "Credential Access"],
|
|
51478
|
+
impactReduction: 40,
|
|
51479
|
+
implementationCost: 15e3,
|
|
51480
|
+
description: "Training prevents human error attacks"
|
|
51481
|
+
},
|
|
51482
|
+
15: {
|
|
51483
|
+
controlName: "Service Provider Management",
|
|
51484
|
+
mitrePhases: ["Resource Development", "Initial Access"],
|
|
51485
|
+
impactReduction: 12,
|
|
51486
|
+
implementationCost: 2e4,
|
|
51487
|
+
description: "Third-party risk management reduces supply chain attacks"
|
|
51488
|
+
},
|
|
51489
|
+
16: {
|
|
51490
|
+
controlName: "Application Software Security",
|
|
51491
|
+
mitrePhases: ["Initial Access", "Execution"],
|
|
51492
|
+
impactReduction: 20,
|
|
51493
|
+
implementationCost: 8e4,
|
|
51494
|
+
description: "Secure coding prevents application-based attacks"
|
|
51495
|
+
},
|
|
51496
|
+
17: {
|
|
51497
|
+
controlName: "Incident Response Management",
|
|
51498
|
+
mitrePhases: ["Impact"],
|
|
51499
|
+
impactReduction: 30,
|
|
51500
|
+
implementationCost: 45e3,
|
|
51501
|
+
description: "Faster response reduces breach duration and cost"
|
|
51502
|
+
},
|
|
51503
|
+
18: {
|
|
51504
|
+
controlName: "Penetration Testing",
|
|
51505
|
+
mitrePhases: ["Reconnaissance", "Discovery"],
|
|
51506
|
+
impactReduction: 15,
|
|
51507
|
+
implementationCost: 25e3,
|
|
51508
|
+
description: "Testing identifies vulnerabilities before attackers through controlled reconnaissance"
|
|
51509
|
+
}
|
|
51510
|
+
};
|
|
51511
|
+
const MITRE_DESCRIPTIONS = {
|
|
51512
|
+
"Reconnaissance": "Gathering information to plan future adversary operations, that can be conducted against the target of interest.",
|
|
51513
|
+
"Resource Development": "Establishing resources they can use to support operations during their campaign targeting an organization.",
|
|
51514
|
+
"Initial Access": "Trying to get into your network through various entry points like spear phishing emails or exploiting public applications.",
|
|
51515
|
+
"Execution": "Running malicious code on local or remote systems to achieve their objectives.",
|
|
51516
|
+
"Persistence": "Maintaining their foothold in your systems by surviving reboots, changed credentials, and other interruptions.",
|
|
51517
|
+
"Privilege Escalation": "Gaining higher-level permissions to access more resources and sensitive information.",
|
|
51518
|
+
"Defense Evasion": "Avoiding detection by disabling security tools, obfuscating content, or hiding artifacts.",
|
|
51519
|
+
"Credential Access": "Stealing account names and passwords to gain access to systems and data.",
|
|
51520
|
+
"Discovery": "Learning about your environment and internal network to understand what they control and benefits their goals.",
|
|
51521
|
+
"Lateral Movement": "Moving through your environment to reach their objective, often accessing remote systems.",
|
|
51522
|
+
"Collection": "Gathering information and files that are of interest to their goal and objectives.",
|
|
51523
|
+
"Command and Control": "Communicating with compromised systems to control them and exfiltrate data.",
|
|
51524
|
+
"Exfiltration": "Stealing data from your network, often over their command and control channel.",
|
|
51525
|
+
"Impact": "Manipulating, interrupting, or destroying your systems and data to achieve their goals."
|
|
51526
|
+
};
|
|
51527
|
+
const SelectedTacticDetails = ({
|
|
51528
|
+
selectedTactic,
|
|
51529
|
+
breachData,
|
|
51530
|
+
onClose
|
|
51531
|
+
}) => {
|
|
51532
|
+
const selectedPhase = breachData.mitrePhases.find(
|
|
51533
|
+
(p2) => p2.phase === selectedTactic
|
|
51534
|
+
);
|
|
51535
|
+
if (!selectedPhase) return null;
|
|
51536
|
+
const getRiskLevelColor2 = (riskLevel) => {
|
|
51537
|
+
switch (riskLevel) {
|
|
51538
|
+
case "low":
|
|
51539
|
+
return "#10b981";
|
|
51540
|
+
case "medium":
|
|
51541
|
+
return "#f59e0b";
|
|
51542
|
+
case "high":
|
|
51543
|
+
return "#ef4444";
|
|
51544
|
+
default:
|
|
51545
|
+
return "#6b7280";
|
|
51546
|
+
}
|
|
51547
|
+
};
|
|
51548
|
+
const relevantCISControls = Object.entries(CIS_MITRE_MAPPING).filter(([_, mapping]) => mapping.mitrePhases.includes(selectedTactic)).map(([controlNumber, mapping]) => {
|
|
51549
|
+
const controlNum = parseInt(controlNumber);
|
|
51550
|
+
const controlMapping = breachData.controlMappings.find(
|
|
51551
|
+
(c2) => c2.controlNumber === controlNum
|
|
51552
|
+
);
|
|
51553
|
+
return {
|
|
51554
|
+
controlNumber: controlNum,
|
|
51555
|
+
controlName: mapping.controlName,
|
|
51556
|
+
implemented: (controlMapping == null ? void 0 : controlMapping.implemented) || false,
|
|
51557
|
+
description: mapping.description
|
|
51558
|
+
};
|
|
51559
|
+
}).sort((a2, b) => a2.controlNumber - b.controlNumber);
|
|
51560
|
+
return /* @__PURE__ */ jsxs("div", { className: "mt-4 p-4 bg-white rounded-lg border relative", children: [
|
|
51561
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-start mb-3", children: [
|
|
51562
|
+
/* @__PURE__ */ jsx("h5", { className: "font-semibold text-gray-900", children: selectedPhase.phase }),
|
|
51563
|
+
/* @__PURE__ */ jsx(
|
|
51564
|
+
Button$1,
|
|
51565
|
+
{
|
|
51566
|
+
variant: "ghost",
|
|
51567
|
+
size: "sm",
|
|
51568
|
+
onClick: onClose,
|
|
51569
|
+
className: "h-6 w-6 p-0 hover:bg-gray-100",
|
|
51570
|
+
children: /* @__PURE__ */ jsx(X$2, { className: "h-4 w-4" })
|
|
51571
|
+
}
|
|
51572
|
+
)
|
|
51573
|
+
] }),
|
|
51574
|
+
/* @__PURE__ */ jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-700", children: MITRE_DESCRIPTIONS[selectedPhase.phase] || "No description available for this tactic." }) }),
|
|
51575
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4 text-sm mb-4", children: [
|
|
51576
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
51577
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-600", children: "Coverage:" }),
|
|
51578
|
+
/* @__PURE__ */ jsxs("span", { className: "ml-2 font-medium", children: [
|
|
51579
|
+
selectedPhase.coverage,
|
|
51580
|
+
"%"
|
|
51581
|
+
] })
|
|
51582
|
+
] }),
|
|
51583
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
51584
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-600", children: "Risk Level:" }),
|
|
51585
|
+
/* @__PURE__ */ jsx(
|
|
51586
|
+
"span",
|
|
51587
|
+
{
|
|
51588
|
+
className: "ml-2 font-medium",
|
|
51589
|
+
style: { color: getRiskLevelColor2(selectedPhase.riskLevel) },
|
|
51590
|
+
children: selectedPhase.riskLevel.charAt(0).toUpperCase() + selectedPhase.riskLevel.slice(1)
|
|
51591
|
+
}
|
|
51592
|
+
)
|
|
51593
|
+
] }),
|
|
51594
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
51595
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-600", children: "Protection Status:" }),
|
|
51596
|
+
/* @__PURE__ */ jsx("span", { className: "ml-2 font-medium", children: selectedPhase.coverage >= 80 ? "Well Protected" : selectedPhase.coverage >= 50 ? "Partially Protected" : "Vulnerable" })
|
|
51597
|
+
] })
|
|
51598
|
+
] }),
|
|
51599
|
+
/* @__PURE__ */ jsxs("div", { className: "border-t pt-4", children: [
|
|
51600
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2 mb-3", children: [
|
|
51601
|
+
/* @__PURE__ */ jsx(Shield, { className: "h-4 w-4 text-blue-600" }),
|
|
51602
|
+
/* @__PURE__ */ jsx("h6", { className: "font-medium text-gray-900", children: "CIS Controls That Improve This Tactic" })
|
|
51603
|
+
] }),
|
|
51604
|
+
relevantCISControls.length > 0 ? /* @__PURE__ */ jsx("div", { className: "space-y-2", children: relevantCISControls.map((control) => /* @__PURE__ */ jsxs(
|
|
51605
|
+
"div",
|
|
51606
|
+
{
|
|
51607
|
+
className: `p-3 rounded-lg border ${control.implemented ? "bg-green-50 border-green-200" : "bg-orange-50 border-orange-200"}`,
|
|
51608
|
+
children: [
|
|
51609
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-start justify-between mb-1", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
51610
|
+
/* @__PURE__ */ jsxs("span", { className: "font-medium text-sm", children: [
|
|
51611
|
+
"CIS Control ",
|
|
51612
|
+
control.controlNumber
|
|
51613
|
+
] }),
|
|
51614
|
+
/* @__PURE__ */ jsx(
|
|
51615
|
+
Badge,
|
|
51616
|
+
{
|
|
51617
|
+
variant: control.implemented ? "default" : "secondary",
|
|
51618
|
+
className: control.implemented ? "bg-green-100 text-green-800 border-green-200" : "bg-orange-100 text-orange-800 border-orange-200",
|
|
51619
|
+
children: control.implemented ? "Implemented" : "Not Implemented"
|
|
51620
|
+
}
|
|
51621
|
+
)
|
|
51622
|
+
] }) }),
|
|
51623
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-800 mb-1", children: control.controlName }),
|
|
51624
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-gray-600", children: control.description })
|
|
51625
|
+
]
|
|
51626
|
+
},
|
|
51627
|
+
control.controlNumber
|
|
51628
|
+
)) }) : /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 italic", children: "No CIS controls are mapped to this MITRE tactic." }),
|
|
51629
|
+
relevantCISControls.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-3 p-2 bg-blue-50 rounded border border-blue-200", children: /* @__PURE__ */ jsxs("p", { className: "text-xs text-blue-700", children: [
|
|
51630
|
+
/* @__PURE__ */ jsx("strong", { children: "Coverage Calculation:" }),
|
|
51631
|
+
" This tactic's",
|
|
51632
|
+
" ",
|
|
51633
|
+
selectedPhase.coverage,
|
|
51634
|
+
"% coverage is based on",
|
|
51635
|
+
" ",
|
|
51636
|
+
relevantCISControls.filter((c2) => c2.implemented).length,
|
|
51637
|
+
" of",
|
|
51638
|
+
" ",
|
|
51639
|
+
relevantCISControls.length,
|
|
51640
|
+
" relevant CIS controls being implemented."
|
|
51641
|
+
] }) })
|
|
51642
|
+
] })
|
|
51643
|
+
] });
|
|
51644
|
+
};
|
|
51645
|
+
const MITRETacticsOverview = ({
|
|
51646
|
+
breachData,
|
|
51647
|
+
selectedTactic,
|
|
51648
|
+
setSelectedTactic,
|
|
51649
|
+
onTacticClick
|
|
51650
|
+
}) => {
|
|
51651
|
+
var _a;
|
|
51652
|
+
const [selectedStep, setSelectedStep] = React__default.useState(null);
|
|
51653
|
+
const getRiskLevelColor2 = (riskLevel) => {
|
|
51654
|
+
switch (riskLevel) {
|
|
51655
|
+
case "low":
|
|
51656
|
+
return "#10b981";
|
|
51657
|
+
case "medium":
|
|
51658
|
+
return "#f59e0b";
|
|
51659
|
+
case "high":
|
|
51660
|
+
return "#ef4444";
|
|
51661
|
+
default:
|
|
51662
|
+
return "#6b7280";
|
|
51663
|
+
}
|
|
51664
|
+
};
|
|
51665
|
+
const handleClosePopup = () => {
|
|
51666
|
+
setSelectedTactic(null);
|
|
51667
|
+
};
|
|
51668
|
+
return /* @__PURE__ */ jsxs("div", { className: "bg-gray-50 p-4 rounded-lg", children: [
|
|
51669
|
+
/* @__PURE__ */ jsx("h4", { className: "font-medium text-sm mb-3", children: "MITRE ATT&CK Kill Chain Coverage - 4 Attack Steps" }),
|
|
51670
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 mb-4", children: "Click on any step to explore individual tactics" }),
|
|
51671
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-4 mb-6", children: ATTACK_STEPS.map((step) => {
|
|
51672
|
+
var _a2;
|
|
51673
|
+
const stepData = (_a2 = breachData.attackSteps) == null ? void 0 : _a2.find(
|
|
51674
|
+
(s2) => s2.stepId === step.stepId
|
|
51675
|
+
);
|
|
51676
|
+
const coverage = (stepData == null ? void 0 : stepData.coverage) || 0;
|
|
51677
|
+
const riskLevel = (stepData == null ? void 0 : stepData.riskLevel) || "medium";
|
|
51678
|
+
return /* @__PURE__ */ jsxs(
|
|
51679
|
+
"div",
|
|
51680
|
+
{
|
|
51681
|
+
className: `bg-white p-3 rounded-lg border cursor-pointer transition-all duration-200 ${selectedStep === step.stepId ? "ring-2 ring-blue-300 shadow-md" : "hover:shadow-sm"}`,
|
|
51682
|
+
onClick: () => {
|
|
51683
|
+
setSelectedStep(
|
|
51684
|
+
selectedStep === step.stepId ? null : step.stepId
|
|
51685
|
+
);
|
|
51686
|
+
onTacticClick("");
|
|
51687
|
+
},
|
|
51688
|
+
onKeyDown: (e) => {
|
|
51689
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
51690
|
+
e.preventDefault();
|
|
51691
|
+
setSelectedStep(
|
|
51692
|
+
selectedStep === step.stepId ? null : step.stepId
|
|
51693
|
+
);
|
|
51694
|
+
onTacticClick("");
|
|
51695
|
+
}
|
|
51696
|
+
},
|
|
51697
|
+
role: "button",
|
|
51698
|
+
tabIndex: 0,
|
|
51699
|
+
"aria-label": `${step.stepName}: ${step.description}`,
|
|
51700
|
+
children: [
|
|
51701
|
+
/* @__PURE__ */ jsx(
|
|
51702
|
+
"div",
|
|
51703
|
+
{
|
|
51704
|
+
className: "text-sm font-medium mb-1",
|
|
51705
|
+
style: { color: step.color },
|
|
51706
|
+
children: step.stepName
|
|
51707
|
+
}
|
|
51708
|
+
),
|
|
51709
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-600 mb-2", children: step.description }),
|
|
51710
|
+
/* @__PURE__ */ jsx("div", { className: "w-full h-2 bg-gray-200 rounded-full overflow-hidden mb-1", children: /* @__PURE__ */ jsx(
|
|
51711
|
+
"div",
|
|
51712
|
+
{
|
|
51713
|
+
className: "h-full transition-all duration-300",
|
|
51714
|
+
style: {
|
|
51715
|
+
width: `${coverage}%`,
|
|
51716
|
+
backgroundColor: step.color
|
|
51717
|
+
}
|
|
51718
|
+
}
|
|
51719
|
+
) }),
|
|
51720
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between text-xs", children: [
|
|
51721
|
+
/* @__PURE__ */ jsxs("span", { className: "text-gray-600", children: [
|
|
51722
|
+
coverage,
|
|
51723
|
+
"% Coverage"
|
|
51724
|
+
] }),
|
|
51725
|
+
/* @__PURE__ */ jsxs("span", { style: { color: getRiskLevelColor2(riskLevel) }, children: [
|
|
51726
|
+
riskLevel.charAt(0).toUpperCase() + riskLevel.slice(1),
|
|
51727
|
+
" Risk"
|
|
51728
|
+
] })
|
|
51729
|
+
] })
|
|
51730
|
+
]
|
|
51731
|
+
},
|
|
51732
|
+
step.stepId
|
|
51733
|
+
);
|
|
51734
|
+
}) }),
|
|
51735
|
+
selectedStep && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
51736
|
+
/* @__PURE__ */ jsxs("h5", { className: "font-medium text-sm mb-3", children: [
|
|
51737
|
+
"Individual Tactics for",
|
|
51738
|
+
" ",
|
|
51739
|
+
(_a = ATTACK_STEPS.find((s2) => s2.stepId === selectedStep)) == null ? void 0 : _a.stepName,
|
|
51740
|
+
" ",
|
|
51741
|
+
"(Click to view details)"
|
|
51742
|
+
] }),
|
|
51743
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-2", children: breachData.mitrePhases.filter((phase) => {
|
|
51744
|
+
const step = getTacticStep(phase.phase);
|
|
51745
|
+
return (step == null ? void 0 : step.stepId) === selectedStep;
|
|
51746
|
+
}).sort((a2, b) => {
|
|
51747
|
+
const stepA = getTacticStep(a2.phase);
|
|
51748
|
+
const stepB = getTacticStep(b.phase);
|
|
51749
|
+
const stepOrder = [
|
|
51750
|
+
"get-in",
|
|
51751
|
+
"sneak-around",
|
|
51752
|
+
"take-control",
|
|
51753
|
+
"stay-hidden"
|
|
51754
|
+
];
|
|
51755
|
+
const indexA = stepA ? stepOrder.indexOf(stepA.stepId) : 999;
|
|
51756
|
+
const indexB = stepB ? stepOrder.indexOf(stepB.stepId) : 999;
|
|
51757
|
+
if (indexA !== indexB) {
|
|
51758
|
+
return indexA - indexB;
|
|
51759
|
+
}
|
|
51760
|
+
return a2.phase.localeCompare(b.phase);
|
|
51761
|
+
}).map((phase) => {
|
|
51762
|
+
const step = getTacticStep(phase.phase);
|
|
51763
|
+
return /* @__PURE__ */ jsxs(
|
|
51764
|
+
"div",
|
|
51765
|
+
{
|
|
51766
|
+
className: `text-center cursor-pointer transition-all duration-200 p-2 rounded border ${selectedTactic === phase.phase ? "bg-white shadow-md ring-2 ring-blue-300" : "hover:bg-white hover:shadow-sm"}`,
|
|
51767
|
+
onClick: () => onTacticClick(phase.phase),
|
|
51768
|
+
onKeyDown: (e) => {
|
|
51769
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
51770
|
+
e.preventDefault();
|
|
51771
|
+
onTacticClick(phase.phase);
|
|
51772
|
+
}
|
|
51773
|
+
},
|
|
51774
|
+
role: "button",
|
|
51775
|
+
tabIndex: 0,
|
|
51776
|
+
"aria-label": phase.phase,
|
|
51777
|
+
children: [
|
|
51778
|
+
/* @__PURE__ */ jsx(
|
|
51779
|
+
"div",
|
|
51780
|
+
{
|
|
51781
|
+
className: "text-xs font-medium truncate mb-1",
|
|
51782
|
+
title: phase.phase,
|
|
51783
|
+
children: phase.phase
|
|
51784
|
+
}
|
|
51785
|
+
),
|
|
51786
|
+
step && /* @__PURE__ */ jsx(
|
|
51787
|
+
"div",
|
|
51788
|
+
{
|
|
51789
|
+
className: "text-xs mb-1",
|
|
51790
|
+
style: { color: step.color },
|
|
51791
|
+
children: step.stepName.replace("Step ", "")
|
|
51792
|
+
}
|
|
51793
|
+
),
|
|
51794
|
+
/* @__PURE__ */ jsx("div", { className: "w-full h-2 bg-gray-200 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
51795
|
+
"div",
|
|
51796
|
+
{
|
|
51797
|
+
className: "h-full transition-all duration-300",
|
|
51798
|
+
style: {
|
|
51799
|
+
width: `${phase.coverage}%`,
|
|
51800
|
+
backgroundColor: (step == null ? void 0 : step.color) || getRiskLevelColor2(phase.riskLevel)
|
|
51801
|
+
}
|
|
51802
|
+
}
|
|
51803
|
+
) }),
|
|
51804
|
+
/* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-600 mt-1", children: [
|
|
51805
|
+
phase.coverage,
|
|
51806
|
+
"%"
|
|
51807
|
+
] }),
|
|
51808
|
+
/* @__PURE__ */ jsxs(
|
|
51809
|
+
"div",
|
|
51810
|
+
{
|
|
51811
|
+
className: "text-xs mt-1",
|
|
51812
|
+
style: { color: getRiskLevelColor2(phase.riskLevel) },
|
|
51813
|
+
children: [
|
|
51814
|
+
phase.riskLevel.charAt(0).toUpperCase() + phase.riskLevel.slice(1),
|
|
51815
|
+
" ",
|
|
51816
|
+
"Risk"
|
|
51817
|
+
]
|
|
51818
|
+
}
|
|
51819
|
+
)
|
|
51820
|
+
]
|
|
51821
|
+
},
|
|
51822
|
+
phase.phase
|
|
51823
|
+
);
|
|
51824
|
+
}) })
|
|
51825
|
+
] }),
|
|
51826
|
+
selectedTactic && /* @__PURE__ */ jsx(
|
|
51827
|
+
SelectedTacticDetails,
|
|
51828
|
+
{
|
|
51829
|
+
selectedTactic,
|
|
51830
|
+
breachData,
|
|
51831
|
+
onClose: handleClosePopup
|
|
51832
|
+
}
|
|
51833
|
+
)
|
|
51834
|
+
] });
|
|
51835
|
+
};
|
|
51345
51836
|
const BreachLikelihood = ({ reportData }) => {
|
|
51346
51837
|
var _a;
|
|
51347
51838
|
const { clientData, securityAssessment, breachData } = reportData;
|
|
51839
|
+
const [selectedTactic, setSelectedTactic] = useState(null);
|
|
51348
51840
|
const calculateBreachLikelihood = (protectionLevel) => {
|
|
51349
51841
|
if ((securityAssessment == null ? void 0 : securityAssessment.overall_breach_likelihood) !== null && (securityAssessment == null ? void 0 : securityAssessment.overall_breach_likelihood) !== void 0) {
|
|
51350
51842
|
return Math.round(securityAssessment.overall_breach_likelihood);
|
|
@@ -51433,70 +51925,15 @@ const BreachLikelihood = ({ reportData }) => {
|
|
|
51433
51925
|
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-bold text-slate-900 mb-2", children: "Understanding Your Numbers" }),
|
|
51434
51926
|
/* @__PURE__ */ jsx("p", { className: "text-slate-600", children: "How We Calculate Your Risk" })
|
|
51435
51927
|
] }),
|
|
51436
|
-
/* @__PURE__ */
|
|
51437
|
-
|
|
51438
|
-
|
|
51439
|
-
|
|
51440
|
-
|
|
51441
|
-
|
|
51442
|
-
|
|
51443
|
-
|
|
51444
|
-
|
|
51445
|
-
/* @__PURE__ */ jsxs("p", { children: [
|
|
51446
|
-
/* @__PURE__ */ jsx("strong", { children: "Source:" }),
|
|
51447
|
-
" FBI Internet Crime Reports and cybersecurity research"
|
|
51448
|
-
] }),
|
|
51449
|
-
/* @__PURE__ */ jsxs("p", { children: [
|
|
51450
|
-
/* @__PURE__ */ jsx("strong", { children: "Your result:" }),
|
|
51451
|
-
" ",
|
|
51452
|
-
attackLikelihood,
|
|
51453
|
-
"% chance based on ",
|
|
51454
|
-
currentProtection,
|
|
51455
|
-
"% protection implementation"
|
|
51456
|
-
] })
|
|
51457
|
-
] })
|
|
51458
|
-
] }),
|
|
51459
|
-
/* @__PURE__ */ jsxs("div", { className: "border-2 border-slate-200 rounded-lg p-6", children: [
|
|
51460
|
-
/* @__PURE__ */ jsx(DollarSign, { className: "w-8 h-8 text-red-600 mb-4" }),
|
|
51461
|
-
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold mb-3", children: "Financial Impact" }),
|
|
51462
|
-
/* @__PURE__ */ jsxs("div", { className: "text-sm text-slate-600 space-y-2", children: [
|
|
51463
|
-
/* @__PURE__ */ jsxs("p", { children: [
|
|
51464
|
-
/* @__PURE__ */ jsx("strong", { children: "Based on:" }),
|
|
51465
|
-
" Average costs for businesses your size in your industry"
|
|
51466
|
-
] }),
|
|
51467
|
-
/* @__PURE__ */ jsxs("p", { children: [
|
|
51468
|
-
/* @__PURE__ */ jsx("strong", { children: "Source:" }),
|
|
51469
|
-
" IBM Cost of Data Breach Report 2024"
|
|
51470
|
-
] }),
|
|
51471
|
-
/* @__PURE__ */ jsxs("p", { children: [
|
|
51472
|
-
/* @__PURE__ */ jsx("strong", { children: "Your result:" }),
|
|
51473
|
-
" $",
|
|
51474
|
-
baseCost ? baseCost.toLocaleString() : "510,000",
|
|
51475
|
-
" potential cost for small ",
|
|
51476
|
-
clientData.industry,
|
|
51477
|
-
" business"
|
|
51478
|
-
] })
|
|
51479
|
-
] })
|
|
51480
|
-
] }),
|
|
51481
|
-
/* @__PURE__ */ jsxs("div", { className: "border-2 border-slate-200 rounded-lg p-6", children: [
|
|
51482
|
-
/* @__PURE__ */ jsx(Shield, { className: "w-8 h-8 text-blue-600 mb-4" }),
|
|
51483
|
-
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold mb-3", children: "Protection Value" }),
|
|
51484
|
-
/* @__PURE__ */ jsxs("div", { className: "text-sm text-slate-600 space-y-2", children: [
|
|
51485
|
-
/* @__PURE__ */ jsxs("p", { children: [
|
|
51486
|
-
/* @__PURE__ */ jsx("strong", { children: "Based on:" }),
|
|
51487
|
-
" How much each security control reduces attack success"
|
|
51488
|
-
] }),
|
|
51489
|
-
/* @__PURE__ */ jsxs("p", { children: [
|
|
51490
|
-
/* @__PURE__ */ jsx("strong", { children: "Source:" }),
|
|
51491
|
-
" NIST Cybersecurity Framework effectiveness data"
|
|
51492
|
-
] }),
|
|
51493
|
-
/* @__PURE__ */ jsxs("p", { children: [
|
|
51494
|
-
/* @__PURE__ */ jsx("strong", { children: "Your result:" }),
|
|
51495
|
-
" Each control's value calculated from proven risk reduction"
|
|
51496
|
-
] })
|
|
51497
|
-
] })
|
|
51498
|
-
] })
|
|
51499
|
-
] }),
|
|
51928
|
+
/* @__PURE__ */ jsx(
|
|
51929
|
+
MITRETacticsOverview,
|
|
51930
|
+
{
|
|
51931
|
+
breachData,
|
|
51932
|
+
selectedTactic,
|
|
51933
|
+
setSelectedTactic,
|
|
51934
|
+
onTacticClick: setSelectedTactic
|
|
51935
|
+
}
|
|
51936
|
+
),
|
|
51500
51937
|
/* @__PURE__ */ jsxs("div", { className: "bg-slate-50 rounded-lg p-6 mb-6", children: [
|
|
51501
51938
|
/* @__PURE__ */ jsx("h3", { className: "text-xl font-bold mb-4", children: "Our Approach" }),
|
|
51502
51939
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-slate-700", children: "We use the same data sources that insurance companies and security professionals rely on. Our calculations are conservative - real attack costs are often higher than our estimates." })
|
|
@@ -52400,7 +52837,7 @@ const InsuranceHealthScore = ({ reportData }) => {
|
|
|
52400
52837
|
className: `rounded-lg p-6 text-white text-center ${scoreCategoryData.bgColor}`,
|
|
52401
52838
|
children: [
|
|
52402
52839
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center space-x-2 mb-2", children: [
|
|
52403
|
-
/* @__PURE__ */ jsx("div", { className: "w-
|
|
52840
|
+
/* @__PURE__ */ jsx("div", { className: "w-12 h-12 p-2 rounded-full bg-white/20 flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "text-lg font-bold", children: score }) }),
|
|
52404
52841
|
/* @__PURE__ */ jsx("h3", { className: "text-2xl font-bold", children: "INSURANCE HEALTH SCORE" })
|
|
52405
52842
|
] }),
|
|
52406
52843
|
/* @__PURE__ */ jsx("p", { className: "text-4xl font-bold", children: `${score}/850` }),
|
|
@@ -52461,33 +52898,36 @@ const InsuranceHealthScore = ({ reportData }) => {
|
|
|
52461
52898
|
insuranceHealthData.responses
|
|
52462
52899
|
);
|
|
52463
52900
|
return domains.map((domain, index2) => {
|
|
52464
|
-
let statusPill = "";
|
|
52465
52901
|
let statusClass = "";
|
|
52466
52902
|
const percentage = domain.percentage || 0;
|
|
52467
52903
|
if (percentage === 0) {
|
|
52468
|
-
|
|
52469
|
-
statusClass = "bg-red-500 text-white";
|
|
52904
|
+
statusClass = "bg-red-500";
|
|
52470
52905
|
} else if (percentage === 100) {
|
|
52471
|
-
|
|
52472
|
-
statusClass = "bg-green-500 text-white";
|
|
52906
|
+
statusClass = "bg-green-500";
|
|
52473
52907
|
} else {
|
|
52474
|
-
|
|
52475
|
-
statusClass = "bg-yellow-600 text-white";
|
|
52908
|
+
statusClass = "bg-yellow-600";
|
|
52476
52909
|
}
|
|
52477
|
-
return /* @__PURE__ */
|
|
52910
|
+
return /* @__PURE__ */ jsxs(
|
|
52478
52911
|
"div",
|
|
52479
52912
|
{
|
|
52480
52913
|
className: "bg-white border border-slate-200 rounded-lg p-4",
|
|
52481
|
-
children:
|
|
52482
|
-
/* @__PURE__ */
|
|
52483
|
-
|
|
52484
|
-
"
|
|
52914
|
+
children: [
|
|
52915
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between mb-1 text-sm", children: [
|
|
52916
|
+
/* @__PURE__ */ jsx("h5", { className: "font-medium text-slate-900", children: domain.name }),
|
|
52917
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-400", children: [
|
|
52918
|
+
domain.score,
|
|
52919
|
+
"/",
|
|
52920
|
+
domain.maxScore
|
|
52921
|
+
] })
|
|
52922
|
+
] }),
|
|
52923
|
+
/* @__PURE__ */ jsx("div", { className: "w-full bg-gray-200 rounded-full h-3", children: /* @__PURE__ */ jsx(
|
|
52924
|
+
"div",
|
|
52485
52925
|
{
|
|
52486
|
-
className: `
|
|
52487
|
-
|
|
52926
|
+
className: `h-4 rounded-full transition-all duration-500 ${statusClass}`,
|
|
52927
|
+
style: { width: percentage + "%" }
|
|
52488
52928
|
}
|
|
52489
52929
|
) })
|
|
52490
|
-
]
|
|
52930
|
+
]
|
|
52491
52931
|
},
|
|
52492
52932
|
index2
|
|
52493
52933
|
);
|