snyk-docker-plugin
Version:
Snyk CLI docker plugin
230 lines • 8.29 kB
JavaScript
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
;