UNPKG

snyk-docker-plugin

Version:
230 lines 8.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.formatRemediations = exports.display = void 0; const chalk_1 = require("chalk"); const os = require("os"); const dep_graph_1 = require("@snyk/dep-graph"); const BREAK_LINE = os.EOL; const SECTION_PADDING_TO_FORMAT_METADATA = 19; async function display(scanResults, testResults, errors, options) { const result = []; let index = 0; for (const testResult of testResults) { const formattedIssue = []; for (const issue of testResult.issues) { formattedIssue.push(formatIssue(testResult, issue)); } result.push(formattedIssue.join(BREAK_LINE)); result.push(includeSectionSeparator()); const scanResult = scanResults[index]; const metadata = formatMetadataSection(scanResult, testResult); result.push(metadata); result.push(includeSectionSeparator()); const summary = formatSummary(testResult); result.push(summary); result.push(includeSectionSeparator()); const remediations = formatRemediations(testResult); if (remediations) { result.push(remediations); result.push(includeSectionSeparator()); } const suggestions = formatSuggestions(options); if (suggestions) { result.push(suggestions); result.push(includeSectionSeparator()); } const userCTA = formatUserCTA(options); if (userCTA) { result.push(userCTA); } index += 1; } return result.join(BREAK_LINE); } exports.display = display; function includeSectionSeparator() { return BREAK_LINE; } function formatIssue(testResult, issue) { const result = []; const issueData = testResult.issuesData[issue.issueId]; const severity = capitalize(issueData.severity); const pkg = issue.pkgName; const color = getColor(issueData.severity); const header = color(`✗ ${severity} severity vulnerability found in ${pkg}`); const description = ` Description: ${issueData.title}`; const info = ` Info: https://snyk.io/vuln/${issue.issueId}`; const introduced = ` Introduced through: ${formatIntroduced(issueData.from)}`; const from = formatFrom(issueData.from); const fixedIn = formatFixedIn(issue); result.push(header); result.push(description); result.push(info); result.push(introduced); result.push(from); if (fixedIn) { result.push(fixedIn); } result.push(""); return result.join(BREAK_LINE); } function capitalize(word) { return word[0].toUpperCase() + word.slice(1); } function formatIntroduced(fromList) { const result = []; for (const from of fromList) { result.push(from[0]); } return result.join(", "); } function formatFrom(fromList) { const result = []; let counter = 0; const max = 3; for (const localFrom of fromList) { if (counter >= max) { break; } counter += 1; result.push(` From: ${localFrom.join(" > ")}`); } if (fromList.length > max) { result.push(` and ${(fromList.length = max)} more...`); } return result.join(BREAK_LINE); } function formatFixedIn(issue) { if (!issue.fixInfo || !issue.fixInfo.nearestFixedInVersion) { return undefined; } return chalk_1.default.bold.green(` Fixed in: ${issue.fixInfo.nearestFixedInVersion}`); } function formatMetadataSection(scanResult, testResult) { var _a; const result = []; result.push(formatMetadataLine("Organization:", testResult.org)); const packageManager = scanResult.identity.type; result.push(formatMetadataLine("Package manager:", packageManager)); const target = scanResult.target; const projectName = target.image; const image = target.image.replace("docker-image|", ""); result.push(formatMetadataLine("Project name:", projectName)); result.push(formatMetadataLine("Docker image:", image)); if (testResult.docker && testResult.docker.baseImage) { result.push(formatMetadataLine("Base image:", testResult.docker.baseImage)); } if (testResult.licensesPolicy) { result.push(formatMetadataLine("Licenses:", chalk_1.default.green("enabled"))); } const platform = (_a = scanResult.identity.args) === null || _a === void 0 ? void 0 : _a.platform; if (platform) { result.push(formatMetadataLine("Platform:", platform)); } return result.join(BREAK_LINE); } function formatMetadataLine(header, info = "") { return `${chalk_1.default.green(padding(header, SECTION_PADDING_TO_FORMAT_METADATA))} ${info}`; } function formatSummary(testResult) { var _a; const depGraph = (0, dep_graph_1.createFromJSON)(testResult.depGraphData); const pkgCount = ((_a = depGraph === null || depGraph === void 0 ? void 0 : depGraph.getDepPkgs()) === null || _a === void 0 ? void 0 : _a.length) || 0; const pathOrDepsText = `${pkgCount} dependencies`; const testedInfoText = `Tested ${pathOrDepsText} for known issues`; const vulnPathsText = formatVulnSummaryText(testResult.issues); let summaryText = `${testedInfoText}, ${vulnPathsText}`; if (testResult.issues.length === 0) { summaryText = chalk_1.default.green(`✓ ${summaryText}`); } return summaryText; } function formatVulnSummaryText(issues) { if (issues.length > 0) { return chalk_1.default.bold.red(`found ${issues.length} issues.`); } return "no vulnerable paths found."; } function getColor(severity) { let color; switch (severity) { case "low": color = chalk_1.default.bold.blue; break; case "medium": color = chalk_1.default.bold.yellow; break; case "high": color = chalk_1.default.bold.red; break; default: color = chalk_1.default.whiteBright; break; } return color; } function formatRemediations(res) { if (!res.docker || !res.docker.baseImageRemediation) { return ""; } const { advice, message } = res.docker.baseImageRemediation; const out = []; if (advice) { for (const item of advice) { out.push(formatString(item)(item.message)); } } else if (message) { out.push(message); } else { return ""; } return `${out.join(BREAK_LINE)}`; } exports.formatRemediations = formatRemediations; function formatString({ color, bold }) { let formatter = chalk_1.default; if (color && formatter[color]) { formatter = formatter[color]; } if (bold) { formatter = formatter.bold; } return formatter; } function formatSuggestions(options) { if (options.isDockerUser) { return ""; } const dockerSuggestion = []; if (options.config && options.config.disableSuggestions !== "true") { const optOutSuggestions = "To remove this message in the future, please run `snyk config set disableSuggestions=true`"; if (!options.file) { dockerSuggestion.push(chalk_1.default.bold.white("Pro tip: use `--file` option to get base image remediation advice.")); dockerSuggestion.push(chalk_1.default.bold.white(`Example: $ snyk container test ${options.path} --file=path/to/Dockerfile`)); dockerSuggestion.push(BREAK_LINE); dockerSuggestion.push(optOutSuggestions); } else if (!options["exclude-base-image-vulns"]) { dockerSuggestion.push(chalk_1.default.bold.white("Pro tip: use `--exclude-base-image-vulns` to exclude from display Docker base image vulnerabilities.")); dockerSuggestion.push(BREAK_LINE); dockerSuggestion.push(optOutSuggestions); } } return dockerSuggestion.join(BREAK_LINE); } function formatUserCTA(options) { if (options.isDockerUser) { return "For more free scans that keep your images secure, sign up to Snyk at https://dockr.ly/3ePqVcp"; } return ""; } function padding(s, padding) { const padLength = padding - s.length; if (padLength <= 0) { return s; } return s + " ".repeat(padLength); } //# sourceMappingURL=display.js.map