Skip to content

Commit

Permalink
feat: show original severity if overridden by a policy
Browse files Browse the repository at this point in the history
  • Loading branch information
joaolemos committed Aug 14, 2020
1 parent 17552b6 commit 30a8cd7
Show file tree
Hide file tree
Showing 14 changed files with 2,520 additions and 20 deletions.
18 changes: 13 additions & 5 deletions src/cli/commands/protect/prompts.ts
Expand Up @@ -18,7 +18,8 @@ import { parsePackageString as moduleToObject } from 'snyk-module';
import * as config from '../../../lib/config';
import * as snykPolicy from 'snyk-policy';
import chalk from 'chalk';
import { AnnotatedIssue } from '../../../lib/snyk-test/legacy';
import { AnnotatedIssue, SEVERITY } from '../../../lib/snyk-test/legacy';
import { titleCaseText } from '../test/formatters/legacy-format-issue';

const debug = debugModule('snyk');

Expand All @@ -42,7 +43,7 @@ function sort(prop) {
};
}

function createSeverityBasedIssueHeading(msg, severity) {
function createSeverityBasedIssueHeading(msg: string, severity: SEVERITY) {
// Example: ✗ Medium severity vulnerability found in xmldom
const severitiesColourMapping = {
low: {
Expand Down Expand Up @@ -609,14 +610,21 @@ function generatePrompt(
debug('Skipping issues in core package with no upgrade path: ' + id);
}
const vulnIn = vuln.from.slice(-1).pop();
const severity = vuln.severity[0].toUpperCase() + vuln.severity.slice(1);
const severity = titleCaseText(vuln.severity);

let infoLink = ' Info: ' + chalk.underline(config.ROOT);

let messageIntro;
let fromText: boolean | string = false;
const group = vuln.grouped && vuln.grouped.main ? vuln.grouped : false;

let originalSeverityStr = '';
if (vuln.originalSeverity && vuln.originalSeverity !== vuln.severity) {
originalSeverityStr = ` (originally ${titleCaseText(
vuln.originalSeverity,
)})`;
}

if (group) {
infoLink += chalk.underline(
'/package/npm/' + group.affected.name + '/' + group.affected.version,
Expand All @@ -626,7 +634,7 @@ function generatePrompt(
messageIntro = fmt(
'✗ %s %s %s introduced %s %s',
group.count,
severity,
`${severity}${originalSeverityStr}`,
issues,
joiningText,
group.affected.full,
Expand All @@ -639,7 +647,7 @@ function generatePrompt(
infoLink += chalk.underline('/vuln/' + vuln.id);
messageIntro = fmt(
'✗ %s severity %s found in %s, introduced via',
severity,
`${severity}${originalSeverityStr}`,
vuln.type === 'license' ? 'issue' : 'vuln',
vulnIn,
from,
Expand Down
38 changes: 30 additions & 8 deletions src/cli/commands/test/formatters/legacy-format-issue.ts
Expand Up @@ -13,6 +13,7 @@ import {
GroupedVuln,
AnnotatedIssue,
DockerIssue,
SEVERITY,
} from '../../../../lib/snyk-test/legacy';
import { formatLegalInstructions } from './legal-license-instructions';
import { getReachabilityText } from './format-reachability';
Expand All @@ -35,12 +36,13 @@ export function formatIssues(
).join(', ');

const vulnOutput = {
issueHeading: createSeverityBasedIssueHeading(
vuln.metadata.severity,
vuln.metadata.type,
vuln.metadata.name,
false,
),
issueHeading: createSeverityBasedIssueHeading({
severity: vuln.metadata.severity,
originalSeverity: vuln.originalSeverity,
type: vuln.metadata.type,
packageName: vuln.metadata.name,
isNew: false,
}),
introducedThrough: ' Introduced through: ' + uniquePackages,
description: ' Description: ' + vuln.title,
info: ' Info: ' + chalk.underline(config.ROOT + '/vuln/' + vulnID),
Expand Down Expand Up @@ -76,7 +78,21 @@ export function formatIssues(
);
}

function createSeverityBasedIssueHeading(severity, type, packageName, isNew) {
type CreateSeverityBasedIssueHeading = {
severity: SEVERITY;
originalSeverity?: SEVERITY;
type: string;
packageName: string;
isNew: boolean;
};

function createSeverityBasedIssueHeading({
severity,
originalSeverity,
type,
packageName,
isNew,
}: CreateSeverityBasedIssueHeading) {
// Example: ✗ Medium severity vulnerability found in xmldom
const vulnTypeText = type === 'license' ? 'issue' : 'vulnerability';
const severitiesColourMapping = {
Expand All @@ -96,11 +112,17 @@ function createSeverityBasedIssueHeading(severity, type, packageName, isNew) {
},
},
};

let originalSeverityStr = '';
if (originalSeverity && originalSeverity !== severity) {
originalSeverityStr = ` (originally ${titleCaseText(originalSeverity)})`;
}

return (
severitiesColourMapping[severity].colorFunc(
'✗ ' +
titleCaseText(severity) +
' severity ' +
` severity${originalSeverityStr} ` +
vulnTypeText +
' found in ' +
chalk.underline(packageName),
Expand Down
Expand Up @@ -57,6 +57,7 @@ export function formatIssuesWithRemediation(
const vulnData = {
title: vuln.title,
severity: vuln.severity,
originalSeverity: vuln.originalSeverity,
isNew: vuln.isNew,
name: vuln.name,
type: vuln.metadata.type,
Expand Down Expand Up @@ -175,6 +176,7 @@ function constructLicenseText(
basicLicenseInfo[id].paths,
testOptions,
basicLicenseInfo[id].note,
undefined, // We can never override license rules, so no originalSeverity here
basicLicenseInfo[id].legalInstructions,
);
licenseTextArray.push('\n' + licenseText);
Expand Down Expand Up @@ -217,6 +219,7 @@ function constructPatchesText(
basicVulnInfo[id].paths,
testOptions,
basicVulnInfo[id].note,
basicVulnInfo[id].originalSeverity,
);
patchedTextArray.push(patchedText + thisPatchFixes);
}
Expand Down Expand Up @@ -247,6 +250,7 @@ function thisUpgradeFixes(
basicVulnInfo[id].paths,
testOptions,
basicVulnInfo[id].note,
basicVulnInfo[id].originalSeverity,
[],
basicVulnInfo[id].reachability,
basicVulnInfo[id].sampleReachablePaths,
Expand Down Expand Up @@ -400,6 +404,7 @@ function constructUnfixableText(
issueInfo.paths,
testOptions,
issueInfo.note,
issueInfo.originalSeverity,
[],
issue.reachability,
) + `${extraInfo}`,
Expand Down Expand Up @@ -428,6 +433,7 @@ export function formatIssue(
paths: string[][],
testOptions: TestOptions,
note: string | false,
originalSeverity?: SEVERITY,
legalInstructions?: LegalInstruction[],
reachability?: REACHABILITY,
sampleReachablePaths?: SampleReachablePaths,
Expand Down Expand Up @@ -493,11 +499,16 @@ export function formatIssue(
reachablePathsTemplate,
);

let originalSeverityStr = '';
if (originalSeverity && originalSeverity !== severity) {
originalSeverityStr = ` (originally ${titleCaseText(originalSeverity)})`;
}

return (
severitiesColourMapping[severity].colorFunc(
` ✗ ${chalk.bold(title)}${newBadge} [${titleCaseText(
severity,
)} Severity]`,
)} Severity${originalSeverityStr}]`,
) +
reachabilityText +
`[${config.ROOT}/vuln/${id}]` +
Expand Down
1 change: 1 addition & 0 deletions src/cli/commands/test/formatters/types.ts
Expand Up @@ -14,6 +14,7 @@ export interface BasicVulnInfo {
type: string;
title: string;
severity: SEVERITY;
originalSeverity?: SEVERITY;
isNew: boolean;
name: string;
version: string;
Expand Down
1 change: 1 addition & 0 deletions src/cli/commands/test/index.ts
Expand Up @@ -651,6 +651,7 @@ function groupVulnerabilities(vulns): GroupedVuln[] {
map[curr.id].title = curr.title;
map[curr.id].note = curr.note;
map[curr.id].severity = curr.severity as SEVERITY;
map[curr.id].originalSeverity = curr.originalSeverity as SEVERITY;
map[curr.id].isNew = isNewVuln(curr);
map[curr.id].name = curr.name;
map[curr.id].version = curr.version;
Expand Down
2 changes: 2 additions & 0 deletions src/lib/snyk-test/legacy.ts
Expand Up @@ -50,6 +50,7 @@ export interface GroupedVuln {
title: string;
note: string | false;
severity: SEVERITY;
originalSeverity?: SEVERITY;
isNew: boolean;
name: string;
version: string;
Expand Down Expand Up @@ -107,6 +108,7 @@ interface AnnotatedIssue extends IssueData {
isUpgradable: boolean;
isPatchable: boolean;
severity: SEVERITY;
originalSeverity?: SEVERITY;

// These fields present for "node_module" based scans to allow remediation
bundled?: any;
Expand Down

0 comments on commit 30a8cd7

Please sign in to comment.