UNPKG

snyk-docker-plugin

Version:
228 lines 12.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.analyze = void 0; const Debug = require("debug"); const error_utils_1 = require("../error-utils"); const archiveExtractor = require("../extractor"); const go_parser_1 = require("../go-parser"); const inputs_1 = require("../inputs"); const static_1 = require("../inputs/apk/static"); const static_2 = require("../inputs/apt/static"); const static_3 = require("../inputs/base-runtimes/static"); const static_4 = require("../inputs/binaries/static"); const static_5 = require("../inputs/chisel/static"); const static_6 = require("../inputs/distroless/static"); const filePatternStatic = require("../inputs/file-pattern/static"); const static_7 = require("../inputs/java/static"); const static_8 = require("../inputs/dotnet/static"); const static_9 = require("../inputs/node/static"); const static_10 = require("../inputs/os-release/static"); const static_11 = require("../inputs/php/static"); const static_12 = require("../inputs/python/static"); const static_13 = require("../inputs/redHat/static"); const static_14 = require("../inputs/rpm/static"); const option_utils_1 = require("../option-utils"); const applications_1 = require("./applications"); const java_1 = require("./applications/java"); const python_1 = require("./applications/python"); const runtime_common_1 = require("./applications/runtime-common"); const base_runtimes_1 = require("./base-runtimes"); const layer_attribution_1 = require("./layer-attribution"); const osReleaseDetector = require("./os-release"); const apk_1 = require("./package-managers/apk"); const apk_ownership_1 = require("./package-managers/apk-ownership"); const apt_1 = require("./package-managers/apt"); const chisel_1 = require("./package-managers/chisel"); const rpm_1 = require("./package-managers/rpm"); const debug = Debug("snyk"); async function analyze(targetImage, dockerfileAnalysis, imageType, imagePath, globsToFind, options) { const staticAnalysisActions = [ static_1.getApkDbFileContentAction, static_2.getDpkgFileContentAction, static_2.getExtFileContentAction, static_14.getRpmDbFileContentAction, static_14.getRpmSqliteDbFileContentAction, static_14.getRpmNdbFileContentAction, static_5.getChiselManifestAction, ...static_10.getOsReleaseActions, static_4.getNodeBinariesFileContentAction, static_4.getOpenJDKBinariesFileContentAction, static_3.getJavaRuntimeReleaseAction, static_6.getDpkgPackageFileContentAction, static_13.getRedHatRepositoriesContentAction, ]; const checkForGlobs = shouldCheckForGlobs(globsToFind); if (checkForGlobs) { staticAnalysisActions.push(filePatternStatic.generateExtractAction(globsToFind.include, globsToFind.exclude)); } const appScan = !(0, option_utils_1.isTrue)(options["exclude-app-vulns"]); const nodeModulesScan = !(0, option_utils_1.isTrue)(options["exclude-node-modules"]); // A runtime logic enabler flag. Is off by default. const collectApplicationFiles = (0, option_utils_1.isTrue)(options["collect-application-files"]); if (appScan) { const jarActions = [static_7.getJarFileContentAction]; // Include system JARs from /usr/lib if flag is enabled if ((0, option_utils_1.isTrue)(options["include-system-jars"])) { jarActions.push(static_7.getUsrLibJarFileContentAction); } staticAnalysisActions.push(...[ static_9.getNodeAppFileContentAction, static_11.getPhpAppFileContentAction, static_12.getPoetryAppFileContentAction, static_12.getPipAppFileContentAction, static_8.getDotnetAppFileContentAction, ...jarActions, go_parser_1.getGoModulesContentAction, ]); if (collectApplicationFiles) { staticAnalysisActions.push(static_9.getNodeJsTsAppFileContentAction, static_12.getPythonAppFileContentAction); } } const timings = {}; let phaseStart = Date.now(); const { imageId, manifestLayers, extractedLayers, orderedLayers, symlinks, rootFsLayers, autoDetectedUserInstructions, platform, imageLabels, imageCreationTime, containerConfig, history, } = await archiveExtractor.extractImageContent(imageType, imagePath, staticAnalysisActions, options); timings.imageExtractionMs = Date.now() - phaseStart; const [apkDbFileContent, aptDbFileContent, rpmDbFileContent, rpmSqliteDbFileContent, rpmNdbFileContent, chiselPackages,] = await Promise.all([ (0, static_1.getApkDbFileContent)(extractedLayers), (0, static_2.getAptDbFileContent)(extractedLayers), (0, static_14.getRpmDbFileContent)(extractedLayers), (0, static_14.getRpmSqliteDbFileContent)(extractedLayers), (0, static_14.getRpmNdbFileContent)(extractedLayers), (0, static_5.getChiselManifestContent)(extractedLayers), ]); const distrolessAptFiles = (0, static_6.getAptFiles)(extractedLayers); const manifestFiles = []; if (checkForGlobs) { const matchingFiles = filePatternStatic.getMatchingFiles(extractedLayers); manifestFiles.push(...matchingFiles); } let osRelease; try { osRelease = await osReleaseDetector.detectStatically(extractedLayers, dockerfileAnalysis); } catch (err) { debug(`Could not detect OS release: ${(0, error_utils_1.getErrorMessage)(err)}`); throw new Error("Failed to detect OS release"); } const redHatRepositories = (0, static_13.getRedHatRepositoriesFromExtractedLayers)(extractedLayers); let results; try { phaseStart = Date.now(); results = await Promise.all([ (0, apk_1.analyze)(targetImage, apkDbFileContent), (0, apt_1.analyze)(targetImage, aptDbFileContent, osRelease), (0, rpm_1.analyze)(targetImage, [...rpmDbFileContent, ...rpmNdbFileContent], redHatRepositories, osRelease), (0, rpm_1.mapRpmSqlitePackages)(targetImage, rpmSqliteDbFileContent, redHatRepositories, osRelease), (0, apt_1.analyzeDistroless)(targetImage, distrolessAptFiles, osRelease), (0, chisel_1.analyze)(targetImage, chiselPackages), ]); timings.osPackageAnalysisMs = Date.now() - phaseStart; } catch (err) { debug(`Could not detect installed OS packages: ${(0, error_utils_1.getErrorMessage)(err)}`); throw new Error("Failed to detect installed OS packages"); } let introducingLayerByPackage; const layerAttributionWarnings = []; if ((0, option_utils_1.isTrue)(options["layer-attribution"]) && rootFsLayers && orderedLayers && orderedLayers.length > 0) { phaseStart = Date.now(); // See `checkHistoryAlignment` for why misalignment is only a warning. const misalignmentWarning = (0, layer_attribution_1.checkHistoryAlignment)(rootFsLayers, history); if (misalignmentWarning) { layerAttributionWarnings.push(misalignmentWarning); debug(misalignmentWarning); } // `results` carries one entry per DB *format* (e.g. RPM BDB/NDB and RPM // SQLite are separate, both `AnalysisType.Rpm`); attribution is keyed on // `AnalyzeType` and reads every format for that ecosystem internally. // Deduping by ecosystem happens inside the helper. if (results.some((r) => r.Analysis.length > 0)) { const attribution = await (0, layer_attribution_1.computeOsLayerAttribution)(results, orderedLayers, rootFsLayers, targetImage, osRelease, redHatRepositories); introducingLayerByPackage = attribution.introducingLayerByPackage; for (const warning of attribution.warnings) { layerAttributionWarnings.push(warning); debug(warning); } } timings.layerAttributionMs = Date.now() - phaseStart; } phaseStart = Date.now(); const binaries = (0, static_4.getBinariesHashes)(extractedLayers); const javaRuntime = (0, base_runtimes_1.detectJavaRuntime)(extractedLayers); const baseRuntimes = javaRuntime ? [javaRuntime] : undefined; timings.binariesAndRuntimeDetectionMs = Date.now() - phaseStart; const applicationDependenciesScanResults = []; if (appScan) { phaseStart = Date.now(); const nodeDependenciesScanResults = await (0, applications_1.nodeFilesToScannedProjects)((0, inputs_1.getFileContent)(extractedLayers, static_9.getNodeAppFileContentAction.actionName), nodeModulesScan, (0, apk_ownership_1.isChainguardDistro)(osRelease)); let nodeApplicationFilesScanResults = []; if (collectApplicationFiles) { nodeApplicationFilesScanResults = (0, runtime_common_1.getApplicationFiles)((0, inputs_1.getFileContent)(extractedLayers, static_9.getNodeJsTsAppFileContentAction.actionName), "node", "npm"); } timings.nodeAnalysisMs = Date.now() - phaseStart; phaseStart = Date.now(); const phpDependenciesScanResults = await (0, applications_1.phpFilesToScannedProjects)((0, inputs_1.getFileContent)(extractedLayers, static_11.getPhpAppFileContentAction.actionName)); timings.phpAnalysisMs = Date.now() - phaseStart; phaseStart = Date.now(); const poetryDependenciesScanResults = await (0, applications_1.poetryFilesToScannedProjects)((0, inputs_1.getFileContent)(extractedLayers, static_12.getPoetryAppFileContentAction.actionName)); timings.poetryAnalysisMs = Date.now() - phaseStart; phaseStart = Date.now(); const pipDependenciesScanResults = await (0, python_1.pipFilesToScannedProjects)((0, inputs_1.getFileContent)(extractedLayers, static_12.getPipAppFileContentAction.actionName)); let pythonApplicationFilesScanResults = []; if (collectApplicationFiles) { pythonApplicationFilesScanResults = (0, runtime_common_1.getApplicationFiles)((0, inputs_1.getFileContent)(extractedLayers, static_12.getPythonAppFileContentAction.actionName), "python", "python"); } timings.pipAnalysisMs = Date.now() - phaseStart; phaseStart = Date.now(); const dotnetDependenciesScanResults = await (0, applications_1.dotnetFilesToScannedProjects)((0, inputs_1.getFileContent)(extractedLayers, static_8.getDotnetAppFileContentAction.actionName)); timings.dotnetAnalysisMs = Date.now() - phaseStart; phaseStart = Date.now(); const desiredLevelsOfUnpacking = getNestedJarsDesiredDepth(options); const jarFingerprintScanResults = await (0, java_1.jarFilesToScannedResults)((0, inputs_1.getBufferContent)(extractedLayers, static_7.getJarFileContentAction.actionName), targetImage, desiredLevelsOfUnpacking); timings.jarAnalysisMs = Date.now() - phaseStart; phaseStart = Date.now(); const goModulesScanResult = await (0, go_parser_1.goModulesToScannedProjects)((0, inputs_1.getElfFileContent)(extractedLayers, go_parser_1.getGoModulesContentAction.actionName)); timings.goAnalysisMs = Date.now() - phaseStart; applicationDependenciesScanResults.push(...nodeDependenciesScanResults, ...nodeApplicationFilesScanResults, ...phpDependenciesScanResults, ...poetryDependenciesScanResults, ...pipDependenciesScanResults, ...pythonApplicationFilesScanResults, ...dotnetDependenciesScanResults, ...jarFingerprintScanResults, ...goModulesScanResult); } return { imageId, osRelease, platform, results, binaries, baseRuntimes, imageLayers: manifestLayers, rootFsLayers, introducingLayerByPackage, layerAttributionWarnings: layerAttributionWarnings.length > 0 ? layerAttributionWarnings : undefined, applicationDependenciesScanResults, manifestFiles, autoDetectedUserInstructions, imageLabels, imageCreationTime, containerConfig, history, symlinks, timings, }; } exports.analyze = analyze; function getNestedJarsDesiredDepth(options) { const nestedJarsOption = options["nested-jars-depth"] || options["shaded-jars-depth"]; let nestedJarsDepth = 1; const depthNumber = Number(nestedJarsOption); if (!isNaN(depthNumber) && depthNumber >= 0) { nestedJarsDepth = depthNumber; } return nestedJarsDepth; } function shouldCheckForGlobs(globsToFind) { return globsToFind.include.length > 0; } //# sourceMappingURL=static-analyzer.js.map