Skip to content

Commit

Permalink
[Osquery] Fix sql query parser logic (#114932)
Browse files Browse the repository at this point in the history
  • Loading branch information
patrykkopycinski authored Oct 14, 2021
1 parent 81a84a8 commit dfbb397
Showing 1 changed file with 134 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import { produce } from 'immer';
import { isEmpty, find, orderBy, sortedUniqBy, isArray, map } from 'lodash';
import { each, isEmpty, find, orderBy, sortedUniqBy, isArray, map, reduce, get } from 'lodash';
import React, {
forwardRef,
useCallback,
Expand Down Expand Up @@ -624,30 +624,47 @@ export const ECSMappingEditorField = ({ field, query, fieldRef }: ECSMappingEdit
return currentValue;
}

const tablesOrderMap =
ast?.from?.value?.reduce(
(
acc: { [x: string]: number },
table: { value: { alias?: { value: string }; value: { value: string } } },
index: number
) => {
acc[table.value.alias?.value ?? table.value.value.value] = index;
return acc;
},
{}
) ?? {};

const astOsqueryTables: Record<string, OsqueryColumn[]> =
const astOsqueryTables: Record<
string,
{
columns: OsqueryColumn[];
order: number;
}
> =
ast?.from?.value?.reduce(
(
acc: { [x: string]: OsqueryColumn[] },
table: { value: { alias?: { value: string }; value: { value: string } } }
) => {
const osqueryTable = find(osquerySchema, ['name', table.value.value.value]);

if (osqueryTable) {
acc[table.value.alias?.value ?? table.value.value.value] = osqueryTable.columns;
acc: {
[x: string]: {
columns: OsqueryColumn[];
order: number;
};
},
table: {
value: {
left?: { value: { value: string }; alias?: { value: string } };
right?: { value: { value: string }; alias?: { value: string } };
value?: { value: string };
alias?: { value: string };
};
}
) => {
each(['value.left', 'value.right', 'value'], (valueKey) => {
if (valueKey) {
const osqueryTable = find(osquerySchema, [
'name',
get(table, `${valueKey}.value.value`),
]);

if (osqueryTable) {
acc[
get(table, `${valueKey}.alias.value`) ?? get(table, `${valueKey}.value.value`)
] = {
columns: osqueryTable.columns,
order: Object.keys(acc).length,
};
}
}
});

return acc;
},
Expand All @@ -659,75 +676,107 @@ export const ECSMappingEditorField = ({ field, query, fieldRef }: ECSMappingEdit
return currentValue;
}

/*
Simple query
select * from users;
*/
if (
ast?.selectItems?.value?.length &&
ast?.selectItems?.value[0].value === '*' &&
ast.from?.value?.length &&
ast?.from.value[0].value?.value?.value &&
astOsqueryTables[ast.from.value[0].value.value.value]
) {
const tableName =
ast.from.value[0].value.alias?.value ?? ast.from.value[0].value.value.value;

return astOsqueryTables[ast.from.value[0].value.value.value].map((osqueryColumn) => ({
label: osqueryColumn.name,
value: {
name: osqueryColumn.name,
description: osqueryColumn.description,
table: tableName,
tableOrder: tablesOrderMap[tableName],
suggestion_label: osqueryColumn.name,
},
}));
}

/*
Advanced query
select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;
*/
const suggestions =
isArray(ast?.selectItems?.value) &&
ast?.selectItems?.value
// @ts-expect-error update types
?.map((selectItem) => {
const [table, column] = selectItem.value?.split('.');

if (column === '*' && astOsqueryTables[table]) {
return astOsqueryTables[table].map((osqueryColumn) => ({
label: osqueryColumn.name,
value: {
name: osqueryColumn.name,
description: osqueryColumn.description,
table,
tableOrder: tablesOrderMap[table],
suggestion_label: `${osqueryColumn.name}`,
},
}));
}
?.map((selectItem: { type: string; value: string; hasAs: boolean; alias?: string }) => {
if (selectItem.type === 'Identifier') {
/*
select * from routes, uptime;
*/
if (ast?.selectItems?.value.length === 1 && selectItem.value === '*') {
return reduce(
astOsqueryTables,
(acc, { columns: osqueryColumns, order: tableOrder }, table) => {
acc.push(
...osqueryColumns.map((osqueryColumn) => ({
label: osqueryColumn.name,
value: {
name: osqueryColumn.name,
description: osqueryColumn.description,
table,
tableOrder,
suggestion_label: osqueryColumn.name,
},
}))
);
return acc;
},
[] as OsquerySchemaOption[]
);
}

if (astOsqueryTables && astOsqueryTables[table]) {
const osqueryColumn = find(astOsqueryTables[table], ['name', column]);

if (osqueryColumn) {
const label = selectItem.hasAs ? selectItem.alias : column;

return [
{
label,
value: {
name: osqueryColumn.name,
description: osqueryColumn.description,
table,
tableOrder: tablesOrderMap[table],
suggestion_label: `${label}`,
},
/*
select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;
*/

const [table, column] = selectItem.value.includes('.')
? selectItem.value?.split('.')
: [Object.keys(astOsqueryTables)[0], selectItem.value];

if (column === '*' && astOsqueryTables[table]) {
const { columns: osqueryColumns, order: tableOrder } = astOsqueryTables[table];
return osqueryColumns.map((osqueryColumn) => ({
label: osqueryColumn.name,
value: {
name: osqueryColumn.name,
description: osqueryColumn.description,
table,
tableOrder,
suggestion_label: `${osqueryColumn.name}`,
},
];
}));
}

if (astOsqueryTables[table]) {
const osqueryColumn = find(astOsqueryTables[table].columns, ['name', column]);

if (osqueryColumn) {
const label = selectItem.hasAs ? selectItem.alias : column;

return [
{
label,
value: {
name: osqueryColumn.name,
description: osqueryColumn.description,
table,
tableOrder: astOsqueryTables[table].order,
suggestion_label: `${label}`,
},
},
];
}
}
}

/*
SELECT pid, uid, name, ROUND((
(user_time + system_time) / (cpu_time.tsb - cpu_time.itsb)
) * 100, 2) AS percentage
FROM processes, (
SELECT (
SUM(user) + SUM(nice) + SUM(system) + SUM(idle) * 1.0) AS tsb,
SUM(COALESCE(idle, 0)) + SUM(COALESCE(iowait, 0)) AS itsb
FROM cpu_time
) AS cpu_time
ORDER BY user_time+system_time DESC
LIMIT 5;
*/

if (selectItem.type === 'FunctionCall' && selectItem.hasAs) {
return [
{
label: selectItem.alias,
value: {
name: selectItem.alias,
description: '',
table: '',
tableOrder: -1,
suggestion_label: selectItem.alias,
},
},
];
}

return [];
Expand Down

0 comments on commit dfbb397

Please sign in to comment.