Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public class ThreatActorAction extends AbstractThreatDetectionAction {
List<String> host;
int startTs;
int endTs;
Boolean successfulExploit;
String splunkUrl;
String splunkToken;
String actorIp;
Expand Down Expand Up @@ -103,6 +104,12 @@ public String getActorsCountPerCounty() {
put("start_ts", startTs);
put("end_ts", endTs);
put("latestAttack", templatesContext);
if (successfulExploit != null) {
put("successful_exploit", successfulExploit);
}
if (status != null && !status.isEmpty()) {
put("status", status);
}
}
};
String msg = objectMapper.valueToTree(body).toString();
Expand Down Expand Up @@ -769,4 +776,12 @@ public Map<String, Integer> getSort() {
public void setSort(Map<String, Integer> sort) {
this.sort = sort;
}

public Boolean getSuccessfulExploit() {
return successfulExploit;
}

public void setSuccessfulExploit(Boolean successfulExploit) {
this.successfulExploit = successfulExploit;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public class ThreatApiAction extends AbstractThreatDetectionAction {
List<String> latestAttack;
int startTs;
int endTs;
Boolean successfulExploit;
String status; // Can be "ACTIVE", "UNDER_REVIEW", or "IGNORED"

@Getter int totalAnalysed;
@Getter int totalAttacks;
Expand Down Expand Up @@ -109,6 +111,12 @@ public String fetchThreatCategoryCount() {
put("start_ts", startTs);
put("end_ts", endTs);
put("latestAttack", getTemplates(latestAttack));
if (successfulExploit != null) {
put("successful_exploit", successfulExploit);
}
if (status != null && !status.isEmpty()) {
put("status", status);
}
}
};
String msg = objectMapper.valueToTree(body).toString();
Expand Down Expand Up @@ -153,6 +161,12 @@ public String fetchCountBySeverity() {
put("start_ts", startTs);
put("end_ts", endTs);
put("latestAttack", getTemplates(latestAttack));
if (successfulExploit != null) {
put("successful_exploit", successfulExploit);
}
if (status != null && !status.isEmpty()) {
put("status", status);
}
}
};
String msg = objectMapper.valueToTree(body).toString();
Expand Down Expand Up @@ -193,6 +207,12 @@ public String getDailyThreatActorsCount() {
put("start_ts", startTs);
put("end_ts", endTs);
put("latestAttack", templatesContext);
if (successfulExploit != null) {
put("successful_exploit", successfulExploit);
}
if (status != null && !status.isEmpty()) {
put("status", status);
}
}
};
String msg = objectMapper.valueToTree(body).toString();
Expand Down Expand Up @@ -242,6 +262,12 @@ public String getThreatActivityTimeline() {
put("start_ts", startTs);
put("end_ts", endTs);
put("latestAttack", templatesContext);
if (successfulExploit != null) {
put("successful_exploit", successfulExploit);
}
if (status != null && !status.isEmpty()) {
put("status", status);
}
}
};
String msg = objectMapper.valueToTree(body).toString();
Expand Down Expand Up @@ -342,6 +368,12 @@ public String fetchThreatTopNData() {
put("end_ts", endTs);
put("latestAttack", templatesContext);
put("limit", 5);
if (successfulExploit != null) {
put("successful_exploit", successfulExploit);
}
if (status != null && !status.isEmpty()) {
put("status", status);
}
}
};
String msg = objectMapper.valueToTree(body).toString();
Expand Down Expand Up @@ -446,6 +478,21 @@ public void setEndTs(int endTs) {
public void setLatestAttack(List<String> latestAttack) {
this.latestAttack = latestAttack;
}

public Boolean getSuccessfulExploit() {
return successfulExploit;
}

public void setSuccessfulExploit(Boolean successfulExploit) {
this.successfulExploit = successfulExploit;
}

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

}

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useReducer, useState, useCallback } from 'react'
import PageWithMultipleCards from "../../components/layouts/PageWithMultipleCards"
import { Box, DataTable, HorizontalGrid, HorizontalStack, Icon, Text, VerticalStack, Badge } from '@shopify/polaris';
import { Box, DataTable, HorizontalGrid, HorizontalStack, Icon, Text, VerticalStack, Badge, Checkbox, Button, Popover, ActionList } from '@shopify/polaris';
import SummaryCard from '../dashboard/new_components/SummaryCard';
import { ArrowUpMinor, ArrowDownMinor } from '@shopify/polaris-icons';
import InfoCard from '../dashboard/new_components/InfoCard';
Expand All @@ -22,6 +22,9 @@ import api from './api';

function ThreatDashboardPage() {
const [loading, setLoading] = useState(true);
const [status, setStatus] = useState(''); // Default: show all
const [onlySuccessfulExploits, setOnlySuccessfulExploits] = useState(false); // Default: show all
const [statusPopoverActive, setStatusPopoverActive] = useState(false);

// Summary metrics state
const [summaryMetrics, setSummaryMetrics] = useState({
Expand Down Expand Up @@ -65,7 +68,7 @@ function ThreatDashboardPage() {
// Row 1: Summary metrics - Use getDailyThreatActorsCount API
let summaryResponse = null
try {
summaryResponse = await api.getDailyThreatActorsCount(startTimestamp, endTimestamp, [])
summaryResponse = await api.getDailyThreatActorsCount(startTimestamp, endTimestamp, [], onlySuccessfulExploits, status)
if (summaryResponse) {
// Use actorsCounts latest entry for active actors similar to ThreatSummary.jsx
let activeActorsValue = summaryResponse.totalActive || 0
Expand Down Expand Up @@ -110,7 +113,7 @@ function ThreatDashboardPage() {

// Severity Distribution - Use API
try {
const severityResponse = await api.fetchCountBySeverity(startTimestamp, endTimestamp)
const severityResponse = await api.fetchCountBySeverity(startTimestamp, endTimestamp, [], onlySuccessfulExploits, status)

if (severityResponse?.categoryCounts && Array.isArray(severityResponse.categoryCounts)) {
const categoryCounts = severityResponse.categoryCounts
Expand Down Expand Up @@ -162,7 +165,7 @@ function ThreatDashboardPage() {

// Row 4: Top Attacked Hosts and APIs via common API
try {
const topResponse = await api.fetchThreatTopNData(startTimestamp, endTimestamp, [], 5)
const topResponse = await api.fetchThreatTopNData(startTimestamp, endTimestamp, [], 5, onlySuccessfulExploits, status)
if (topResponse?.topApis && Array.isArray(topResponse.topApis)) {
setTopAttackedApis(topResponse.topApis)
} else {
Expand Down Expand Up @@ -193,7 +196,7 @@ function ThreatDashboardPage() {
} finally {
setLoading(false)
}
}, [startTimestamp, endTimestamp])
}, [startTimestamp, endTimestamp, onlySuccessfulExploits, status])


useEffect(() => {
Expand Down Expand Up @@ -275,6 +278,8 @@ function ThreatDashboardPage() {
<ThreatSankeyChart
startTimestamp={startTimestamp}
endTimestamp={endTimestamp}
successfulExploit={onlySuccessfulExploits}
status={status}
/>
)

Expand All @@ -283,6 +288,8 @@ function ThreatDashboardPage() {
<ThreatWorldMap
startTimestamp={startTimestamp}
endTimestamp={endTimestamp}
successfulExploit={onlySuccessfulExploits}
status={status}
style={{
width: "100%",
marginRight: "auto",
Expand Down Expand Up @@ -422,7 +429,12 @@ function ThreatDashboardPage() {

// Row 3: Stacked category breakdown (uses same API as Sankey)
const row3Cards = (
<ThreatCategoryStackedChart startTimestamp={startTimestamp} endTimestamp={endTimestamp} />
<ThreatCategoryStackedChart
startTimestamp={startTimestamp}
endTimestamp={endTimestamp}
successfulExploit={onlySuccessfulExploits}
status={status}
/>
)

const dashboardRows = [
Expand Down Expand Up @@ -457,7 +469,64 @@ function ThreatDashboardPage() {
}
isFirstPage={true}
components={pageContent}
primaryAction={<DateRangeFilter initialDispatch={currDateRange} dispatch={(dateObj) => dispatchCurrDateRange({ type: "update", period: dateObj.period, title: dateObj.title, alias: dateObj.alias })} />}
primaryAction={
<HorizontalStack gap="4" align="end">
<Button
pressed={onlySuccessfulExploits}
onClick={() => setOnlySuccessfulExploits(!onlySuccessfulExploits)}
>
Only successful Attacks
</Button>
<Popover
active={statusPopoverActive}
activator={
<Button onClick={() => setStatusPopoverActive(!statusPopoverActive)} disclosure>
{status === '' ? 'All Statuses' : status === 'ACTIVE' ? 'Active' : status === 'UNDER_REVIEW' ? 'Under Review' : 'Ignored'}
</Button>
}
onClose={() => setStatusPopoverActive(false)}
>
<Popover.Pane>
<ActionList
items={[
{
content: 'All Statuses',
onAction: () => {
setStatus('');
setStatusPopoverActive(false);
}
},
{
content: 'Active',
onAction: () => {
setStatus('ACTIVE');
setStatusPopoverActive(false);
}
},
{
content: 'Under Review',
onAction: () => {
setStatus('UNDER_REVIEW');
setStatusPopoverActive(false);
}
},
{
content: 'Ignored',
onAction: () => {
setStatus('IGNORED');
setStatusPopoverActive(false);
}
}
]}
/>
</Popover.Pane>
</Popover>
<DateRangeFilter
initialDispatch={currDateRange}
dispatch={(dateObj) => dispatchCurrDateRange({ type: "update", period: dateObj.period, title: dateObj.title, alias: dateObj.alias })}
/>
</HorizontalStack>
}
/>
}
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import SampleDetails from "./components/SampleDetails";
import threatDetectionRequests from "./api";
import tempFunc from "./dummyData";
import NormalSampleDetails from "./components/NormalSampleDetails";
import { HorizontalGrid, VerticalStack, HorizontalStack, Popover, Button, ActionList, Box, Icon, Badge, Text} from "@shopify/polaris";
import { HorizontalGrid, VerticalStack, HorizontalStack, Popover, Button, ActionList, Box, Icon, Badge, Text, Checkbox, Select} from "@shopify/polaris";
import { FileMinor } from '@shopify/polaris-icons';
import TopThreatTypeChart from "./components/TopThreatTypeChart";
import api from "./api";
Expand Down Expand Up @@ -519,7 +519,14 @@ function ThreatDetectionPage() {
/>
}
isFirstPage={true}
primaryAction={<DateRangeFilter initialDispatch={currDateRange} dispatch={(dateObj) => dispatchCurrDateRange({ type: "update", period: dateObj.period, title: dateObj.title, alias: dateObj.alias })} />}
primaryAction={
<HorizontalStack gap="4" align="end">
<DateRangeFilter
initialDispatch={currDateRange}
dispatch={(dateObj) => dispatchCurrDateRange({ type: "update", period: dateObj.period, title: dateObj.title, alias: dateObj.alias })}
/>
</HorizontalStack>
}
components={components}
secondaryActions={secondaryActionsComp}
/>
Expand Down
Loading
Loading