Skip to content

Commit

Permalink
fix: add pinning advice back to legacy formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
lwywoo committed Oct 28, 2019
1 parent 0c60ac3 commit e6ce153
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 22 deletions.
40 changes: 34 additions & 6 deletions src/cli/commands/test/formatters/legacy-format-issue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ import chalk from 'chalk';
import * as config from '../../../../lib/config';
import { Options, TestOptions, ShowVulnPaths } from '../../../../lib/types';
import { isLocalFolder } from '../../../../lib/detect';
import { WIZARD_SUPPORTED_PACKAGE_MANAGERS } from '../../../../lib/package-managers';
import parsePackageNameVersion = require('snyk-module');
import {
WIZARD_SUPPORTED_PACKAGE_MANAGERS,
PINNING_SUPPORTED_PACKAGE_MANAGERS,
SupportedPackageManagers,
} from '../../../../lib/package-managers';
import {
GroupedVuln,
AnnotatedIssue,
DockerIssue
DockerIssue,
} from '../../../../lib/snyk-test/legacy';
import { formatLegalInstructions } from './legal-license-instructions';

Expand Down Expand Up @@ -46,7 +51,11 @@ export function formatIssues(
extraInfo: vuln.note ? chalk.bold('\n Note: ' + vuln.note) : '',
remediationInfo:
vuln.metadata.type !== 'license' && localPackageTest
? createRemediationText(vuln, packageManager)
? createRemediationText(
vuln,
packageManager,
!!options.pinningSupported,
)
: '',
fixedIn: options.docker ? createFixedInText(vuln) : '',
dockerfilePackage: options.docker ? dockerfileInstructionText(vuln) : '',
Expand Down Expand Up @@ -167,12 +176,30 @@ function createFixedInText(vuln: GroupedVuln): string {
return '';
}

function createRemediationText(vuln, packageManager) {
function createRemediationText(
vuln: GroupedVuln,
packageManager: SupportedPackageManagers,
pinningSupported: boolean,
): string {
let wizardHintText = '';
if (WIZARD_SUPPORTED_PACKAGE_MANAGERS.includes(packageManager)) {
wizardHintText = 'Run `snyk wizard` to explore remediation options.';
}

if (
pinningSupported &&
vuln.fixedIn &&
PINNING_SUPPORTED_PACKAGE_MANAGERS.includes(packageManager)
) {
const toVersion = vuln.fixedIn.join(' or ');
const transitive = vuln.list.every((i) => i.from.length > 2);

const action = transitive ? 'Pin the transitive' : 'Update the';
return chalk.bold(
`\n Remediation:\n ${action} dependency ${vuln.name} to version ${toVersion}`,
);
}

if (vuln.isFixable === true) {
const upgradePathsArray = _.uniq(
vuln.list.map((v) => {
Expand All @@ -187,7 +214,8 @@ function createRemediationText(vuln, packageManager) {
v.upgradePath.length > 0
? ` (triggers upgrades to ${v.upgradePath.join(' > ')})`
: '';
const testedPackageName = v.upgradePath[0].split('@');
const testedPackageName = parsePackageNameVersion(v
.upgradePath[0] as string);
return (
`You've tested an outdated version of ${testedPackageName[0]}.` +
+` Upgrade to ${v.upgradePath[0]}${selfUpgradeInfo}`
Expand All @@ -209,7 +237,7 @@ function createRemediationText(vuln, packageManager) {
}),
);
return chalk.bold(
`\n Remediation: \n ${upgradePathsArray.join('\n ')}`,
`\n Remediation:\n ${upgradePathsArray.join('\n ')}`,
);
}

Expand Down
12 changes: 9 additions & 3 deletions src/cli/commands/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
getSeverityValue,
} from './formatters/remediation-based-format-issues';
import * as analytics from '../../../lib/analytics';
import { isFeatureFlagSupportedForOrg } from '../../../lib/feature-flags';

const debug = Debug('snyk');
const SEPARATOR = '\n-------------------------------------------------------\n';
Expand Down Expand Up @@ -167,10 +168,15 @@ async function test(...args: MethodArgs): Promise<string> {
throw err;
}

const pinningSupported =
results.find((r) => (r as LegacyVulnApiResult).packageManager === 'pip') &&
(await isFeatureFlagSupportedForOrg('pythonPinningAdvice')).ok;

let response = results
.map((unused, i) =>
displayResult(results[i] as LegacyVulnApiResult, resultOptions[i]),
)
.map((unused, i) => {
resultOptions[i].pinningSupported = pinningSupported;
return displayResult(results[i] as LegacyVulnApiResult, resultOptions[i]);
})
.join(`\n${SEPARATOR}`);

if (notSuccess) {
Expand Down
1 change: 1 addition & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface TestOptions {
interactive: boolean;
'prune-repeated-subdependencies'?: boolean;
showVulnPaths: ShowVulnPaths;
pinningSupported?: boolean;
}
export interface ProtectOptions {
loose: boolean;
Expand Down
36 changes: 32 additions & 4 deletions test/acceptance/cli.acceptance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1566,7 +1566,14 @@ test('`test pip-app --file=requirements.txt`', async (t) => {
await cli.test('pip-app', {
file: 'requirements.txt',
});
const req = server.popRequest();
let req = server.popRequest();
t.equal(req.method, 'GET', 'makes GET request');
t.match(
req.url,
'cli-config/feature-flags/pythonPinningAdvice',
'to correct url',
);
req = server.popRequest();
t.equal(req.method, 'POST', 'makes POST request');
t.equal(
req.headers['x-snyk-cli-version'],
Expand Down Expand Up @@ -1617,7 +1624,14 @@ test('`test pipenv-app --file=Pipfile`', async (t) => {
await cli.test('pipenv-app', {
file: 'Pipfile',
});
const req = server.popRequest();
let req = server.popRequest();
t.equal(req.method, 'GET', 'makes GET request');
t.match(
req.url,
'cli-config/feature-flags/pythonPinningAdvice',
'to correct url',
);
req = server.popRequest();
t.equal(req.method, 'POST', 'makes POST request');
t.equal(
req.headers['x-snyk-cli-version'],
Expand Down Expand Up @@ -1673,7 +1687,14 @@ test('`test pip-app-transitive-vuln --file=requirements.txt (actionableCliRemedi
fs.readFileSync('pip-app-transitive-vuln/cli-output.txt', 'utf8'),
);
}
const req = server.popRequest();
let req = server.popRequest();
t.equal(req.method, 'GET', 'makes GET request');
t.match(
req.url,
'cli-config/feature-flags/pythonPinningAdvice',
'to correct url',
);
req = server.popRequest();
t.equal(req.method, 'POST', 'makes POST request');
t.equal(
req.headers['x-snyk-cli-version'],
Expand Down Expand Up @@ -1731,7 +1752,14 @@ test('`test pip-app-transitive-vuln --file=requirements.txt (actionableCliRemedi
),
);
}
const req = server.popRequest();
let req = server.popRequest();
t.equal(req.method, 'GET', 'makes GET request');
t.match(
req.url,
'cli-config/feature-flags/pythonPinningAdvice',
'to correct url',
);
req = server.popRequest();
t.equal(req.method, 'POST', 'makes POST request');
t.equal(
req.headers['x-snyk-cli-version'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,32 @@ Testing pip-app-transitive-vuln...
Info: http://localhost:12345/vuln/SNYK-PYTHON-JINJA2-174126
Introduced through: flask@0.12.2
From: flask@0.12.2 > Jinja2@2.9.6
Remediation:
Upgrade direct dependency flask@0.12.2 to flask@0.12.2 (triggers upgrades to flask@0.12.2)
Remediation:
Pin the transitive dependency Jinja2 to version 2.10.1

✗ High severity vulnerability found in flask
Description: Improper Input Validation
Info: http://localhost:12345/vuln/SNYK-PYTHON-FLASK-42185
Introduced through: flask@0.12.2
From: flask@0.12.2
Remediation:
Upgrade direct dependency flask@0.12.2 to flask@0.12.3 (triggers upgrades to flask@0.12.3)
Remediation:
Update the dependency flask to version 0.12.3

✗ High severity vulnerability found in flask
Description: Denial of Service (DOS)
Info: http://localhost:12345/vuln/SNYK-PYTHON-FLASK-451637
Introduced through: flask@0.12.2
From: flask@0.12.2
Remediation:
Upgrade direct dependency flask@0.12.2 to flask@1.0 (triggers upgrades to flask@1.0)
Remediation:
Update the dependency flask to version 1.0

✗ High severity vulnerability found in Werkzeug
Description: Insufficient Randomness
Info: http://localhost:12345/vuln/SNYK-PYTHON-WERKZEUG-458931
Introduced through: flask@0.12.2
From: flask@0.12.2 > Werkzeug@0.12.2
Remediation:
Upgrade direct dependency flask@0.12.2 to flask@0.12.2 (triggers upgrades to flask@0.12.2)
Remediation:
Pin the transitive dependency Werkzeug to version 0.15.3



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,4 +324,4 @@
"org": "kyegupov"
},
"filesystemPolicy": false
}
}

0 comments on commit e6ce153

Please sign in to comment.