Skip to content

Commit

Permalink
Merge pull request #599 from Security-Onion-Solutions/cogburn/tuning-…
Browse files Browse the repository at this point in the history
…history

Overrides Added to Detection History
  • Loading branch information
coreyogburn authored Jul 31, 2024
2 parents 07c0cb2 + 4015c0c commit 60de0b4
Show file tree
Hide file tree
Showing 6 changed files with 516 additions and 161 deletions.
12 changes: 12 additions & 0 deletions html/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -673,3 +673,15 @@ code {
.warning-message a:visited {
color: white;
}

tbody tr:hover {
background-color: transparent !important;
}

.theme--dark tbody tr:hover:nth-of-type(even) {
background-color: rgba(45, 45, 45, 0.25) !important;
}

.theme--light tbody tr:hover:nth-of-type(even) {
background-color: rgba(230, 230, 230, 0.25) !important;
}
403 changes: 250 additions & 153 deletions html/index.html

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions html/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -1208,7 +1208,7 @@ $(document).ready(function() {
},
dateAwareSort(items, index, isDesc) {
items.sort((a, b) => {
if (index[0] === 'createTime' || index[0] === 'updateTime') {
if (index[0] === 'createTime' || index[0] === 'updateTime' || index[0] === 'createdAt' || index[0] === 'updatedAt') {
if (!isDesc[0]) {
return new Date(a[index]) - new Date(b[index]);
}
Expand All @@ -1218,10 +1218,10 @@ $(document).ready(function() {

if (typeof a[index] !== 'undefined') {
if (!isDesc[0]) {
return a[index].toLowerCase().localeCompare(b[index].toLowerCase());
return (a[index]+'').toLowerCase().localeCompare((b[index]+'').toLowerCase());
}

return b[index].toLowerCase().localeCompare(a[index].toLowerCase());
return (b[index]+'').toLowerCase().localeCompare((a[index]+'').toLowerCase());
}
});

Expand Down
2 changes: 2 additions & 0 deletions html/js/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ const i18n = {
invalid: 'Invalid',
ioWait: 'I/O Wait',
invalidCidrOrVar: 'Invalid CIDR Notation or Suricata Variable',
ip: 'IP',
ipCidr: 'IP - CIDR Notation or Suricata Variable',
job: 'Job',
jobIncomplete: 'The job was unable to complete and will retry within a few minutes. Details are available below.',
Expand Down Expand Up @@ -652,6 +653,7 @@ const i18n = {
overrideDeleteHelp: 'Delete this rule override',
overrideDocumentationHelp: 'Click for more information',
overrideExpand: 'Show all override fields',
overrides: 'Overrides',
overview: 'Overview',
owner: 'Owner',
packages: 'Packages',
Expand Down
76 changes: 72 additions & 4 deletions html/js/routes/detection.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ routes.push({ path: '/detection/:id', name: 'detection', component: {
overrideHeaders: {
'elastalert': [
{ text: this.$root.i18n.enabled, value: 'isEnabled' },
{ text: this.$root.i18n.type, value: 'type' },
{ text: this.$root.i18n.type, value: 'type', localize: true },
{ text: this.$root.i18n.track, value: 'track' },
{ text: this.$root.i18n.dateCreated, value: 'createdAt', format: true },
{ text: this.$root.i18n.dateModified, value: 'updatedAt', format: true },
],
'strelka': [], // no overrides
'suricata': [
{ text: this.$root.i18n.enabled, value: 'isEnabled' },
{ text: this.$root.i18n.type, value: 'type' },
{ text: this.$root.i18n.type, value: 'type', localize: true },
{ text: this.$root.i18n.ipVar, value: 'ip' },
{ text: this.$root.i18n.dateCreated, value: 'createdAt', format: true },
{ text: this.$root.i18n.dateModified, value: 'updatedAt', format: true },
Expand Down Expand Up @@ -101,6 +101,38 @@ routes.push({ path: '/detection/:id', name: 'detection', component: {
expanded: [],
loading: false,
},
historyOverrideTableOpts: {
"elastalert": {
sortBy: 'updatedAt',
sortDesc: false,
headers: [
{ text: this.$root.i18n.actions, width: '10.0em' },
{ text: this.$root.i18n.kind, value: 'type' },
{ text: this.$root.i18n.time, value: 'updatedAt' },
{ text: this.$root.i18n.enabled, value: 'isEnabled' },
],
itemsPerPage: 10,
footerProps: { 'items-per-page-options': [10, 50, 250, 1000] },
count: 500,
expanded: [],
loading: false,
},
"suricata": {
sortBy: 'updatedAt',
sortDesc: false,
headers: [
{ text: this.$root.i18n.actions, width: '10.0em' },
{ text: this.$root.i18n.kind, value: 'type' },
{ text: this.$root.i18n.time, value: 'updatedAt' },
{ text: this.$root.i18n.enabled, value: 'isEnabled' },
],
itemsPerPage: 10,
footerProps: { 'items-per-page-options': [10, 50, 250, 1000] },
count: 500,
expanded: [],
loading: false,
},
},
extractedSummary: '',
extractedReferences: [],
extractedLogic: '',
Expand Down Expand Up @@ -140,6 +172,7 @@ routes.push({ path: '/detection/:id', name: 'detection', component: {
'yara': 'strelka',
},
changedKeys: {},
changedOverrideKeys: {},
}},
created() {
this.$root.initializeEditor();
Expand Down Expand Up @@ -504,10 +537,9 @@ routes.push({ path: '/detection/:id', name: 'detection', component: {
if (response && response.data) {
this.history = response.data;

//this.changedKeys[this.history[this.history.length - 1]['id']] = this.findHistoryChange(this.history);

for (var i = 0; i < this.history.length; i++) {
this.$root.populateUserDetails(this.history[i], "userId", "owner");
this.history[i].overrides = this.history[i].overrides || [];
}
}
if (showLoadingIndicator) this.$root.stopLoading();
Expand Down Expand Up @@ -563,7 +595,40 @@ routes.push({ path: '/detection/:id', name: 'detection', component: {
}
}
}

this.changedKeys[id] = retList;

this.findOverrideHistoryChange(id);
},
findOverrideHistoryChange(historyID) {
let index = this.history.findIndex((row) => row.id === historyID);

if (index <= 0) return;

let prev = this.history[index - 1];
let parent = this.history[index];
let releventKeys = ['isEnabled', 'customFilter', 'regex', 'value', 'track', 'ip', 'count', 'seconds'];
let overrideRetList = [];

for (let i = 0; i < parent.overrides.length; i++) {
let retList = [];
let newOverride = parent.overrides[i];
let oldOverride = prev.overrides.find(o => o.createdAt === newOverride.createdAt);

if (oldOverride == null) {
return;
}

for (let key of releventKeys) {
if (oldOverride[key] !== newOverride[key]) {
retList.push(key);
}
}

overrideRetList.push(retList);
}

this.changedOverrideKeys[historyID] = overrideRetList;
},
getDefaultPreset(preset) {
if (this.presets) {
Expand Down Expand Up @@ -1354,6 +1419,9 @@ routes.push({ path: '/detection/:id', name: 'detection', component: {
},
checkChangedKey(id, key) {
return this.changedKeys[id]?.includes(key);
},
checkOverrideChangedKey(id, index, key) {
return this.changedOverrideKeys?.[id]?.[index]?.includes(key);
}
}
}});
178 changes: 177 additions & 1 deletion html/js/routes/detection.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,6 @@ test('getPresets', () => {
});

test('findHistoryChange', () => {

// elastalert
comp.history = [
{
Expand Down Expand Up @@ -831,6 +830,183 @@ test('checkChangedKey', () => {
expect(comp.checkChangedKey(id, 'severity')).toBe(false);
});

test('findOverrideHistoryChange', () => {
// elastalert
comp.history = [
{
id: '1',
overrides: [
{
type: "customFilter",
isEnabled: true,
createdAt: "2024-07-29T10:29:32.421321098-06:00",
updatedAt: "2024-07-29T10:29:32.421321098-06:00",
customFilter: "this:\n that"
},
{
type: "customFilter",
isEnabled: false,
createdAt: "2024-07-29T11:54:34.569557439-06:00",
updatedAt: "2024-07-29T11:54:49.086205751-06:00",
customFilter: "another:\n one"
}
],
},
{
id: '2',
overrides: [
{
type: "customFilter",
isEnabled: true,
createdAt: "2024-07-29T10:29:32.421321098-06:00",
updatedAt: "2024-07-29T10:29:32.421321098-06:00",
customFilter: "this:\n that"
},
{
type: "customFilter",
isEnabled: false,
createdAt: "2024-07-29T11:54:34.569557439-06:00",
updatedAt: "2024-07-29T13:55:29.197427405-06:00",
customFilter: "another:\n two"
}
],
}
];

id = '2';
comp.changedOverrideKeys = {};
comp.findOverrideHistoryChange(id);
expect(Object.keys(comp.changedOverrideKeys).length).toBe(1);

let overrideKeys = comp.changedOverrideKeys[id];
expect(overrideKeys.length).toBe(2);
expect(overrideKeys[0].length).toBe(0);
expect(overrideKeys[1].length).toBe(1);
expect(overrideKeys[1][0]).toBe('customFilter');

// suricata
comp.history = [
{
id: '1',
overrides: [
{
type: "modify",
isEnabled: false,
createdAt: "2024-07-29T14:39:09.544042454-06:00",
updatedAt: "2024-07-29T14:39:21.947393163-06:00",
regex: "rev: 2",
value: "rev: 3"
},
{
type: "suppress",
isEnabled: false,
createdAt: "2024-07-29T14:39:44.312946909-06:00",
updatedAt: "2024-07-29T14:57:49.637548072-06:00",
track: "by_either",
ip: "0.0.0.0/0"
},
{
type: "threshold",
isEnabled: true,
createdAt: "2024-07-29T14:40:17.043093339-06:00",
updatedAt: "2024-07-29T14:40:17.043093339-06:00",
thresholdType: "both",
track: "by_src",
count: 10,
seconds: 60
}
]
},
{
id: '2',
overrides: [
{
type: "modify",
isEnabled: true,
createdAt: "2024-07-29T14:39:09.544042454-06:00",
updatedAt: "2024-07-29T14:39:20.947393160-06:00",
regex: "rev: 2",
value: "rev: 3"
},
{
type: "suppress",
isEnabled: false,
createdAt: "2024-07-29T14:39:44.312946909-06:00",
updatedAt: "2024-07-29T14:57:50.637548070-06:00",
track: "by_src",
ip: "0.0.0.0/1"
},
{
type: "threshold",
isEnabled: true,
createdAt: "2024-07-29T14:40:17.043093339-06:00",
updatedAt: "2024-07-29T14:40:17.043093339-06:00",
thresholdType: "both",
track: "by_src",
"count": 10,
"seconds": 60
}
],
}
];

id = '2';
comp.changedOverrideKeys = {};
comp.findOverrideHistoryChange(id);
expect(Object.keys(comp.changedOverrideKeys).length).toBe(1);

overrideKeys = comp.changedOverrideKeys[id];
expect(overrideKeys.length).toBe(3);
expect(overrideKeys[0].length).toBe(1);
expect(overrideKeys[0][0]).toBe('isEnabled');
expect(overrideKeys[1].length).toBe(2);
expect(overrideKeys[1][0]).toBe('track');
expect(overrideKeys[1][1]).toBe('ip');
expect(overrideKeys[2].length).toBe(0);

id = '1';
comp.changedOverrideKeys = {};
comp.findOverrideHistoryChange(id);
expect(Object.keys(comp.changedOverrideKeys).length).toBe(0);

// elastalert, nothing to diff
comp.history = [
{
id: '1',
overrides: [],
},
{
id: '2',
overrides: [
{
type: "customFilter",
isEnabled: true,
createdAt: "2024-07-29T10:29:32.421321098-06:00",
updatedAt: "2024-07-29T10:29:32.421321098-06:00",
customFilter: "this:\n that"
},
],
}
];

id = '2';
comp.changedOverrideKeys = {};
comp.findOverrideHistoryChange(id);
expect(Object.keys(comp.changedOverrideKeys).length).toBe(0);
});

test('checkOverrideChangedKey', () => {
expect(Object.keys(comp.changedKeys).length).toBe(0);
let id = "BHypPJABXppUUuo3UnEl";
comp.changedOverrideKeys[id] = [[], ['track', 'ip']];
expect(comp.checkOverrideChangedKey(id, 0, 'track')).toBe(false);
expect(comp.checkOverrideChangedKey(id, 1, 'track')).toBe(true);
expect(comp.checkOverrideChangedKey(id, 0, 'ip')).toBe(false);
expect(comp.checkOverrideChangedKey(id, 1, 'ip')).toBe(true);
expect(comp.checkOverrideChangedKey(id, 0, 'seconds')).toBe(false);
expect(comp.checkOverrideChangedKey(id, 1, 'seconds')).toBe(false);
});

test('loadUrlParameters', () => {
let nextTickCalled = 0;
comp.$nextTick = (f) => {
Expand Down

0 comments on commit 60de0b4

Please sign in to comment.