Skip to content

Commit

Permalink
[SIEM][Detection Engine] Fixes tags to accept characters such as AND,…
Browse files Browse the repository at this point in the history
… OR, (, ), ", * (elastic#74003) (elastic#74032)

## Summary

If you create a rule with tags that have an AND, OR, (, ), etc... then you would blow up with an error when you try to filter based off of that like the screen shot below:
<img width="703" alt="Screen Shot 2020-07-31 at 1 55 31 PM" src="https://user-images.githubusercontent.com/1151048/89075547-b3206f80-d33b-11ea-9e7a-30d4a49ac1de.png">

Now you don't blow up:
<img width="1708" alt="Screen Shot 2020-07-31 at 2 37 11 PM" src="https://user-images.githubusercontent.com/1151048/89075553-b582c980-d33b-11ea-807a-7d6a1d1921e8.png">

This fixes it by adding double quotes around the filters and also red/green/TDD unit tests where I first exercised the error conditions then fixed them.   

### Checklist

- [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
  • Loading branch information
FrankHassanabad authored Aug 1, 2020
1 parent 98440bb commit 6e3675a
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
getPrePackagedRulesStatus,
} from './api';
import { ruleMock, rulesMock } from './mock';
import { buildEsQuery } from 'src/plugins/data/common';

const abortCtrl = new AbortController();
const mockKibanaServices = KibanaServices.get as jest.Mock;
Expand Down Expand Up @@ -165,7 +166,7 @@ describe('Detections Rules API', () => {
expect(fetchMock).toHaveBeenCalledWith('/api/detection_engine/rules/_find', {
method: 'GET',
query: {
filter: 'alert.attributes.tags: hello AND alert.attributes.tags: world',
filter: 'alert.attributes.tags: "hello" AND alert.attributes.tags: "world"',
page: 1,
per_page: 20,
sort_field: 'enabled',
Expand All @@ -175,6 +176,75 @@ describe('Detections Rules API', () => {
});
});

test('query with tags KQL parses without errors when tags contain characters such as left parenthesis (', async () => {
await fetchRules({
filterOptions: {
filter: 'ruleName',
sortField: 'enabled',
sortOrder: 'desc',
showCustomRules: true,
showElasticRules: true,
tags: ['('],
},
signal: abortCtrl.signal,
});
const [
[
,
{
query: { filter },
},
],
] = fetchMock.mock.calls;
expect(() => buildEsQuery(undefined, { query: filter, language: 'kuery' }, [])).not.toThrow();
});

test('query KQL parses without errors when filter contains characters such as double quotes', async () => {
await fetchRules({
filterOptions: {
filter: '"test"',
sortField: 'enabled',
sortOrder: 'desc',
showCustomRules: true,
showElasticRules: true,
tags: [],
},
signal: abortCtrl.signal,
});
const [
[
,
{
query: { filter },
},
],
] = fetchMock.mock.calls;
expect(() => buildEsQuery(undefined, { query: filter, language: 'kuery' }, [])).not.toThrow();
});

test('query KQL parses without errors when tags contains characters such as double quotes', async () => {
await fetchRules({
filterOptions: {
filter: '"test"',
sortField: 'enabled',
sortOrder: 'desc',
showCustomRules: true,
showElasticRules: true,
tags: ['"test"'],
},
signal: abortCtrl.signal,
});
const [
[
,
{
query: { filter },
},
],
] = fetchMock.mock.calls;
expect(() => buildEsQuery(undefined, { query: filter, language: 'kuery' }, [])).not.toThrow();
});

test('check parameter url, query with all options', async () => {
await fetchRules({
filterOptions: {
Expand All @@ -191,7 +261,7 @@ describe('Detections Rules API', () => {
method: 'GET',
query: {
filter:
'alert.attributes.name: ruleName AND alert.attributes.tags: "__internal_immutable:false" AND alert.attributes.tags: "__internal_immutable:true" AND alert.attributes.tags: hello AND alert.attributes.tags: world',
'alert.attributes.name: ruleName AND alert.attributes.tags: "__internal_immutable:false" AND alert.attributes.tags: "__internal_immutable:true" AND alert.attributes.tags: "hello" AND alert.attributes.tags: "world"',
page: 1,
per_page: 20,
sort_field: 'enabled',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export const fetchRules = async ({
...(filterOptions.showElasticRules
? [`alert.attributes.tags: "__internal_immutable:true"`]
: []),
...(filterOptions.tags?.map((t) => `alert.attributes.tags: ${t}`) ?? []),
...(filterOptions.tags?.map((t) => `alert.attributes.tags: "${t.replace(/"/g, '\\"')}"`) ?? []),
];

const query = {
Expand Down

0 comments on commit 6e3675a

Please sign in to comment.