Skip to content

Commit

Permalink
refactor sbom component filtering function
Browse files Browse the repository at this point in the history
Signed-off-by: Kaden Emley <kemley@mitre.org>
  • Loading branch information
kemley76 committed Aug 7, 2024
1 parent ada82be commit 55eac14
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function objectToTreeview(obj: Object, id: number): Treeview[] {
*/
function objectDepth(obj: Object, n: number): number {
let max = n;
for (const [key, value] of Object.entries(obj)) {
for (const [_key, value] of Object.entries(obj)) {
if (value instanceof Object) {
const current = objectDepth(value, n + 1);
if (current > max) max = current;
Expand Down
1 change: 0 additions & 1 deletion apps/frontend/src/components/global/Sidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ import Component, {mixins} from 'vue-class-component';
import {Prop} from 'vue-property-decorator';
import {ServerModule} from '../../store/server';
import {EvaluationModule} from '@/store/evaluations';
import _ from 'lodash';
@Component({
components: {
Expand Down
41 changes: 25 additions & 16 deletions apps/frontend/src/store/data_filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import Store from '@/store/store';
import {execution_unique_key} from '@/utilities/format_util';
import {
componentFitsSeverityFilter,
getSbomComponents,
getVulnsFromBomRef,
isOnlySbomFileId,
Expand Down Expand Up @@ -521,6 +522,26 @@ export class FilteredData extends VuexModule {
const components: SBOMComponent[] = [];
const controls = this.controls(filter);
// grab every component from each section and apply a filter if necessary
/* return evaluations
.map(getSbomComponents)
.filter((result) => result.ok)
.map((result: {value: SBOMComponentsResult}) => result.value) // compiler typechecking doesn't know that `value` is guaranteed
.flatMap((pair) => {
const executionKey = execution_unique_key(pair.evaluation);
return pair.components.filter((component) => {
if (!component.affectingVulnerabilities?.length)
return filter.severity?.includes('none');
const vulns = [];
// collect all the controls corresponding to the ids in `affectingVulnerabilities`
for (const vulnRef of component.affectingVulnerabilities) {
const vuln = getVulnsFromBomRef(vulnRef, controls);
if (vuln.ok) vulns.push(vuln!.value);
}
// add the component if it has a vulnerability with an allowable severity
return vulns.some((v) => filter.severity?.includes(v.hdf.severity));
}).map(component => ({...component, key: `${executionKey}-${component['bom-ref']}`}))
}); */

for (const evaluation of evaluations) {
const sbomComponents: Result<SBOMComponent[], null> =
getSbomComponents(evaluation);
Expand All @@ -529,22 +550,10 @@ export class FilteredData extends VuexModule {
const key = `${execution_unique_key(evaluation)}-${component['bom-ref']}`;
// filter components by their affecting vulnerabilities
if (
!component.affectingVulnerabilities ||
component.affectingVulnerabilities.length === 0
) {
if (filter.severity?.includes('none'))
components.push({...component, key});
} else {
const vulns = [];
// collect all the controls corresponding to the ids in `affectingVulnerabilities`
for (const vulnRef of component.affectingVulnerabilities) {
const vuln = getVulnsFromBomRef(vulnRef, controls);
if (vuln.ok) vulns.push(vuln.value);
}
// add the component if it has a vulnerability with an allowable severity
if (vulns.some((v) => filter.severity?.includes(v.hdf.severity)))
components.push({...component, key});
}
!filter.severity ||
componentFitsSeverityFilter(component, filter.severity, controls)
)
components.push({...component, key});
}
}
return components;
Expand Down
24 changes: 23 additions & 1 deletion apps/frontend/src/utilities/sbom_util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from '@/store/report_intake';
import {JSONValue} from '@mitre/hdf-converters/src/utils/parseJson';
import {Result} from '@mitre/hdf-converters/src/utils/result';
import {ContextualizedControl} from 'inspecjs';
import {ContextualizedControl, Severity} from 'inspecjs';
import _ from 'lodash';

export type SBOMProperty = {name: string; value: string};
Expand Down Expand Up @@ -129,6 +129,28 @@ export function getVulnsFromBomRef(
return {ok: false, error: null};
}

export function componentFitsSeverityFilter(
component: SBOMComponent,
severities: Severity[],
controls: readonly ContextualizedControl[]
): boolean {
// if there are no vulnerabilities, then severity: none must be allowed
if (
!component.affectingVulnerabilities ||
component.affectingVulnerabilities.length === 0
) {
return severities.includes('none');
}

// collect all the controls corresponding to the ids in `affectingVulnerabilities`
for (const vulnRef of component.affectingVulnerabilities) {
const vuln = getVulnsFromBomRef(vulnRef, controls);
// return true if the vuln has an allowable severity
if (vuln.ok && severities.includes(vuln.value.hdf.severity)) return true;
}
return false;
}

function getSbomPassthroughSection(
evaluation: SourcedContextualizedEvaluation
): Result<JSONValue, null> {
Expand Down

0 comments on commit 55eac14

Please sign in to comment.