Skip to content

Commit

Permalink
[SIEM] Changes ML conditional links to use tabs, fixes a small bug wi…
Browse files Browse the repository at this point in the history
…th null filterQuery (#45218)

## Summary

Changes the ML drill-downs to use the tabs and re-direct to the Anomalies table when drilled down. 

#45080

Tests for this were both by playing with the Anomalies as well as hand testing that these clickable links below do what I would expect them to do based on the conditional rules of:

* Split comma separated values into OR clauses within KQL.
* Redirect from multiple hosts/ips on the details page to the host over view/detail overview page with a new KQL added as a filter since comma separated values on details would just be errors.
* Remove/Replace any $value$ dollar values that did not have a value as before.

Manual testing is from either the test cases below or by using the ML Anomalies explorerand clicking on the drill down links using the action menu items from Host or IP jobs which look like this:

<img width="352" alt="Screen Shot 2019-09-06 at 4 17 05 PM" src="https://user-images.githubusercontent.com/1151048/64576200-c1852780-d334-11e9-8270-ef97569a2e78.png">


URL manual test cases I used:

Testing conditional ml-network links:
-----

Single IP with a null for the KQL:
http://localhost:5601/app/siem#/ml-network/ip/127.0.0.1?kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))


Single IP with kqlQuery:
http://localhost:5601/app/siem#/ml-network/ip/127.0.0.1?kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))


Multiple IP's with a null for the filterQuery:
http://localhost:5601/app/siem#/ml-network/ip/127.0.0.1,127.0.0.2?kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))


Multiple IP's with a value for the filterQuery:
http://localhost:5601/app/siem#/ml-network/ip/127.0.0.1,127.0.0.2?kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))


Undefined/null IP and a null filterQuery:
http://localhost:5601/app/siem#/ml-network/ip/$ip$?kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))


Undefined/null IP but a value for the filterQuery:
http://localhost:5601/app/siem#/ml-network/ip/$ip$?kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))


Testing conditional host links:


Single host name with a null for the KQL:
http://localhost:5601/app/siem#/ml-hosts/siem-windows?_g=()&kqlQuery=(filterQuery:!n,queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))


Single host name with a variable left in the KQL
http://localhost:5601/app/siem#/ml-hosts/siem-windows?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22$process.name$%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))


Single host name with a value for filterQuery:
http://localhost:5601/app/siem#/ml-hosts/siem-windows?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))


Multiple host names with null for filterQuery

http://localhost:5601/app/siem#/ml-hosts/siem-windows,siem-suricata?_g=()&kqlQuery=(filterQuery:!n,queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))

Multiple host names with a value for filterQuery
http://localhost:5601/app/siem#/ml-hosts/siem-windows,siem-suricata?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))


Undefined/null host name with a null for the KQL:
http://localhost:5601/app/siem#/ml-hosts/$host.name$?_g=()&kqlQuery=(filterQuery:!n,queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))


Undefined/null host name but with a value for filterQuery
http://localhost:5601/app/siem#/ml-hosts/$host.name$?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))

----



Extra misc tests:

3 host names
http://localhost:5601/app/siem#/ml-hosts/suricata-iowa,siem-windows,siem-fake?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22snapd%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-09-09T18:00:00.000Z',kind:absolute,to:'2019-09-09T20:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-09-09T18:00:00.000Z',kind:absolute,to:'2019-09-09T20:59:59.999Z')))


3 ips
http://localhost:5601/app/siem#/ml-network/ip/127.0.0.1,127.0.0.2,127.0.0.3?_g=()&kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T06:00:00.000Z',kind:absolute,to:'2019-08-29T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T06:00:00.000Z',kind:absolute,to:'2019-08-29T05:59:59.999Z')))





### Checklist

Use ~~strikethroughs~~ to remove checklist items you don't feel are applicable to this PR.

- [x] This was checked for cross-browser compatibility, [including a check against IE11](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility)
- [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/master/packages/kbn-i18n/README.md)
- [x] [Documentation](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#writing-documentation) was added for features that require explanation or tutorials
- [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios
- [ ] This was checked for [keyboard-only and screenreader accessibility](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Accessibility_testing_checklist)

### For maintainers

- [x] This was checked for breaking API changes and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)
- [x] This includes a feature addition or change that requires a release note and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)
  • Loading branch information
FrankHassanabad committed Sep 10, 2019
1 parent 67e9eaf commit cde2885
Show file tree
Hide file tree
Showing 8 changed files with 320 additions and 26 deletions.
2 changes: 1 addition & 1 deletion x-pack/legacy/plugins/siem/cypress/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ CYPRESS_baseUrl=http://localhost:5601 CYPRESS_ELASTICSEARCH_USERNAME=elastic CYP

When Cypress tests are run on the command line via `yarn cypress:run`,
reporting artifacts are generated under the `target` directory in the root
of the Kibana, as detailed for each artifact type in the sections bleow.
of the Kibana, as detailed for each artifact type in the sections below.

### HTML Reports

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

/*
* These links are for different test scenarios that try and capture different drill downs into
* ml-network and ml-hosts and are of the flavor of testing:
* A filter being null: (filterQuery:!n)
* A filter being set with single values: filterQuery:(expression:%27process.name%20:%20%22conhost.exe%22%27,kind:kuery)
* A filter being set with multiple values: filterQuery:(expression:%27process.name%20:%20%22conhost.exe,sc.exe%22%27,kind:kuery)
* A filter containing variables not replaced: filterQuery:(expression:%27process.name%20:%20%$process.name$%22%27,kind:kuery)
*
* In different combination with:
* network not being set: $ip$
* host not being set: $host.name$
* ...or...
* network being set normally: 127.0.0.1
* host being set normally: suricata-iowa
* ...or...
* network having multiple values: 127.0.0.1,127.0.0.2
* host having multiple values: suricata-iowa,siem-windows
*/

// Single IP with a null for the filterQuery:
export const mlNetworkSingleIpNullFilterQuery =
"/app/siem#/ml-network/ip/127.0.0.1?kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))";

// Single IP with a value for the filterQuery:
export const mlNetworkSingleIpFilterQuery =
"/app/siem#/ml-network/ip/127.0.0.1?kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))";

// Multiple IPs with a null for the filterQuery:
export const mlNetworkMultipleIpNullFilterQuery =
"/app/siem#/ml-network/ip/127.0.0.1,127.0.0.2?kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))";

// Multiple IPs with a value for the filterQuery:
export const mlNetworkMultipleIpFilterQuery =
"/app/siem#/ml-network/ip/127.0.0.1,127.0.0.2?kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))";

// $ip$ with a null filterQuery:
export const mlNetworkNullFilterQuery =
"/app/siem#/ml-network/ip/$ip$?kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))";

// $ip$ with a value for the filterQuery:
export const mlNetworkFilterQuery =
"/app/siem#/ml-network/ip/$ip$?kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))";

// Single host name with a null for the filterQuery:
export const mlHostSingleHostNullFilterQuery =
"/app/siem#/ml-hosts/siem-windows?_g=()&kqlQuery=(filterQuery:!n,queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))";

// Single host name with a variable in the filterQuery
export const mlHostSingleHostFilterQueryVariable =
"/app/siem#/ml-hosts/siem-windows?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22$process.name$%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))";

// Single host name with a value for filterQuery:
export const mlHostSingleHostFilterQuery =
"/app/siem#/ml-hosts/siem-windows?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))";

// Multiple host names with null for filterQuery
export const mlHostMultiHostNullFilterQuery =
"/app/siem#/ml-hosts/siem-windows,siem-suricata?_g=()&kqlQuery=(filterQuery:!n,queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))";

// Multiple host names with a value for filterQuery
export const mlHostMultiHostFilterQuery =
"/app/siem#/ml-hosts/siem-windows,siem-suricata?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))";

// Undefined/null host name with a null for the KQL:
export const mlHostVariableHostNullFilterQuery =
"/app/siem#/ml-hosts/$host.name$?_g=()&kqlQuery=(filterQuery:!n,queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))";

// Undefined/null host name but with a value for filterQuery
export const mlHostVariableHostFilterQuery =
"/app/siem#/ml-hosts/$host.name$?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))";
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { logout } from '../../lib/logout';
import {
mlNetworkSingleIpNullFilterQuery,
mlNetworkSingleIpFilterQuery,
mlNetworkMultipleIpNullFilterQuery,
mlNetworkMultipleIpFilterQuery,
mlNetworkNullFilterQuery,
mlNetworkFilterQuery,
mlHostSingleHostNullFilterQuery,
mlHostSingleHostFilterQueryVariable,
mlHostSingleHostFilterQuery,
mlHostMultiHostNullFilterQuery,
mlHostMultiHostFilterQuery,
mlHostVariableHostNullFilterQuery,
mlHostVariableHostFilterQuery,
} from '../../lib/ml_conditional_links';
import { loginAndWaitForPage } from '../../lib/util/helpers';
import { KQL_INPUT } from '../../lib/url_state';

describe('ml conditional links', () => {
afterEach(() => {
return logout();
});

it('sets the KQL from a single IP with a value for the filterQuery', () => {
loginAndWaitForPage(mlNetworkSingleIpFilterQuery);
cy.get(KQL_INPUT, { timeout: 5000 }).should(
'have.attr',
'value',
'(process.name: "conhost.exe" or process.name: "sc.exe")'
);
});

it('sets the KQL from a multiple IPs with a null for the filterQuery', () => {
loginAndWaitForPage(mlNetworkMultipleIpNullFilterQuery);
cy.get(KQL_INPUT, { timeout: 5000 }).should(
'have.attr',
'value',
'((source.ip: "127.0.0.1" or destination.ip: "127.0.0.1") or (source.ip: "127.0.0.2" or destination.ip: "127.0.0.2"))'
);
});

it('sets the KQL from a multiple IPs with a value for the filterQuery', () => {
loginAndWaitForPage(mlNetworkMultipleIpFilterQuery);
cy.get(KQL_INPUT, { timeout: 5000 }).should(
'have.attr',
'value',
'((source.ip: "127.0.0.1" or destination.ip: "127.0.0.1") or (source.ip: "127.0.0.2" or destination.ip: "127.0.0.2")) and ((process.name: "conhost.exe" or process.name: "sc.exe"))'
);
});

it('sets the KQL from a $ip$ with a value for the filterQuery', () => {
loginAndWaitForPage(mlNetworkFilterQuery);
cy.get(KQL_INPUT, { timeout: 5000 }).should(
'have.attr',
'value',
'(process.name: "conhost.exe" or process.name: "sc.exe")'
);
});

it('sets the KQL from a single host name with a value for filterQuery', () => {
loginAndWaitForPage(mlHostSingleHostFilterQuery);
cy.get(KQL_INPUT, { timeout: 5000 }).should(
'have.attr',
'value',
'(process.name: "conhost.exe" or process.name: "sc.exe")'
);
});

it('sets the KQL from a multiple host names with null for filterQuery', () => {
loginAndWaitForPage(mlHostMultiHostNullFilterQuery);
cy.get(KQL_INPUT, { timeout: 5000 }).should(
'have.attr',
'value',
'(host.name: "siem-windows" or host.name: "siem-suricata")'
);
});

it('sets the KQL from a multiple host names with a value for filterQuery', () => {
loginAndWaitForPage(mlHostMultiHostFilterQuery);
cy.get(KQL_INPUT, { timeout: 5000 }).should(
'have.attr',
'value',
'(host.name: "siem-windows" or host.name: "siem-suricata") and ((process.name: "conhost.exe" or process.name: "sc.exe"))'
);
});

it('sets the KQL from a undefined/null host name but with a value for filterQuery', () => {
loginAndWaitForPage(mlHostVariableHostFilterQuery);
cy.get(KQL_INPUT, { timeout: 5000 }).should(
'have.attr',
'value',
'(process.name: "conhost.exe" or process.name: "sc.exe")'
);
});

it('redirects from a single IP with a null for the filterQuery', () => {
loginAndWaitForPage(mlNetworkSingleIpNullFilterQuery);
cy.url().should(
'equal',
'http://localhost:5601/app/siem#/network/ip/127.0.0.1?timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))'
);
});

it('redirects from a single IP with a value for the filterQuery', () => {
loginAndWaitForPage(mlNetworkSingleIpFilterQuery);
cy.url().should(
'equal',
"http://localhost:5601/app/siem#/network/ip/127.0.0.1?kqlQuery=(filterQuery:(expression:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)',kind:kuery),queryLocation:network.details)&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))"
);
});

it('redirects from a multiple IPs with a null for the filterQuery', () => {
loginAndWaitForPage(mlNetworkMultipleIpNullFilterQuery);
cy.url().should(
'equal',
"http://localhost:5601/app/siem#/network?kqlQuery=(filterQuery:(expression:'((source.ip:%20%22127.0.0.1%22%20or%20destination.ip:%20%22127.0.0.1%22)%20or%20(source.ip:%20%22127.0.0.2%22%20or%20destination.ip:%20%22127.0.0.2%22))'),queryLocation:network.page)&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))"
);
});

it('redirects from a multiple IPs with a value for the filterQuery', () => {
loginAndWaitForPage(mlNetworkMultipleIpFilterQuery);
cy.url().should(
'equal',
"http://localhost:5601/app/siem#/network?kqlQuery=(filterQuery:(expression:'((source.ip:%20%22127.0.0.1%22%20or%20destination.ip:%20%22127.0.0.1%22)%20or%20(source.ip:%20%22127.0.0.2%22%20or%20destination.ip:%20%22127.0.0.2%22))%20and%20((process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22))',kind:kuery),queryLocation:network.page)&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))"
);
});

it('redirects from a $ip$ with a null filterQuery', () => {
loginAndWaitForPage(mlNetworkNullFilterQuery);
cy.url().should(
'equal',
'http://localhost:5601/app/siem#/network?timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))'
);
});

it('redirects from a $ip$ with a value for the filterQuery', () => {
loginAndWaitForPage(mlNetworkFilterQuery);
cy.url().should(
'equal',
"http://localhost:5601/app/siem#/network?kqlQuery=(filterQuery:(expression:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)',kind:kuery),queryLocation:network.page)&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))"
);
});

it('redirects from a single host name with a null for the filterQuery', () => {
loginAndWaitForPage(mlHostSingleHostNullFilterQuery);
cy.url().should(
'equal',
'http://localhost:5601/app/siem#/hosts/siem-windows/anomalies?_g=()&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))'
);
});

it('redirects from a host name with a variable in the filterQuery', () => {
loginAndWaitForPage(mlHostSingleHostFilterQueryVariable);
cy.url().should(
'equal',
'http://localhost:5601/app/siem#/hosts/siem-windows/anomalies?_g=()&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))'
);
});

it('redirects from a single host name with a value for filterQuery', () => {
loginAndWaitForPage(mlHostSingleHostFilterQuery);
cy.url().should(
'equal',
"http://localhost:5601/app/siem#/hosts/siem-windows/anomalies?_g=()&kqlQuery=(filterQuery:(expression:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)',kind:kuery),queryLocation:hosts.details)&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))"
);
});

it('redirects from a multiple host names with null for filterQuery', () => {
loginAndWaitForPage(mlHostMultiHostNullFilterQuery);
cy.url().should(
'equal',
"http://localhost:5601/app/siem#/hosts/anomalies?_g=()&kqlQuery=(filterQuery:(expression:'(host.name:%20%22siem-windows%22%20or%20host.name:%20%22siem-suricata%22)'),queryLocation:hosts.page)&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))"
);
});

it('redirects from a multiple host names with a value for filterQuery', () => {
loginAndWaitForPage(mlHostMultiHostFilterQuery);
cy.url().should(
'equal',
"http://localhost:5601/app/siem#/hosts/anomalies?_g=()&kqlQuery=(filterQuery:(expression:'(host.name:%20%22siem-windows%22%20or%20host.name:%20%22siem-suricata%22)%20and%20((process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22))',kind:kuery),queryLocation:hosts.page)&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))"
);
});

it('redirects from a undefined/null host name with a null for the KQL', () => {
loginAndWaitForPage(mlHostVariableHostNullFilterQuery);
cy.url().should(
'equal',
'http://localhost:5601/app/siem#/hosts/anomalies?_g=()&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))'
);
});

it('redirects from a undefined/null host name but with a value for filterQuery', () => {
loginAndWaitForPage(mlHostVariableHostFilterQuery);
cy.url().should(
'equal',
"http://localhost:5601/app/siem#/hosts/anomalies?_g=()&kqlQuery=(filterQuery:(expression:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)',kind:kuery),queryLocation:hosts.page)&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))"
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe('add_entities_to_kql', () => {
afterAll(() => {
console.log = originalError;
});

describe('#entityToKql', () => {
test('returns empty string with no entity names defined and an empty entity string', () => {
const entity = entityToKql([], '');
Expand Down Expand Up @@ -165,5 +166,10 @@ describe('add_entities_to_kql', () => {
'(filterQuery:(expression:\'(host.name: "host-name-1" or host.name: "host-name-2") and (process.name : "")\',kind:kuery))'
);
});

test('returns kql expression with a null filterQuery', () => {
const entity = addEntitiesToKql(['host.name'], ['host-1'], '(filterQuery:!n)');
expect(entity).toEqual('(filterQuery:(expression:\'(host.name: "host-1")\'))');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ export const addEntitiesToKql = (
}
return encode(value);
}
} else if (value.filterQuery == null) {
const entitiesKql = entitiesToKql(entityNames, entities);
value.filterQuery = { expression: `(${entitiesKql})` };
return encode(value);
}
}
return kqlQuery;
Expand Down
Loading

0 comments on commit cde2885

Please sign in to comment.