UNPKG

snyk-docker-plugin

Version:
89 lines 3.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getChiselManifestContent = exports.getChiselManifestAction = void 0; const Debug = require("debug"); const path_1 = require("path"); const compression_utils_1 = require("../../compression-utils"); const extractor_1 = require("../../extractor"); const stream_utils_1 = require("../../stream-utils"); const debug = Debug("snyk"); /** * Path to the Chisel manifest file within container images. * This file contains package and slice information for Chisel-built images. */ const CHISEL_MANIFEST_PATH = "/var/lib/chisel/manifest.wall"; /** * Extract action for Ubuntu Chisel manifest files. * * Chisel is Ubuntu's tool for creating minimal container images by installing * only specific "slices" of Debian packages. The manifest.wall file is a * zstd-compressed NDJSON (newline-delimited JSON) file that records all * installed packages, slices, and files for integrity verification and SBOM generation. * * See: https://documentation.ubuntu.com/chisel/en/latest/reference/manifest/ */ exports.getChiselManifestAction = { actionName: "chisel-manifest", filePathMatches: (filePath) => filePath === (0, path_1.normalize)(CHISEL_MANIFEST_PATH), callback: stream_utils_1.streamToBuffer, }; /** * Extracts and parses Chisel package information from Docker image layers. * * Searches for the Chisel manifest file (/var/lib/chisel/manifest.wall), decompresses it, * and extracts package entries. The manifest uses NDJSON format where each line is a * separate JSON object with a "kind" field indicating the entry type. * * @param extractedLayers - Layers extracted from the Docker image * @returns Array of Chisel packages found in the manifest, or empty array if not found */ function getChiselManifestContent(extractedLayers) { const compressedManifest = (0, extractor_1.getContentAsBuffer)(extractedLayers, exports.getChiselManifestAction); if (!compressedManifest) { return []; } try { const decompressed = (0, compression_utils_1.decompressZstd)(compressedManifest); const manifestText = decompressed.toString("utf8"); const packages = []; const lines = manifestText.split("\n"); for (const line of lines) { if (!line.trim()) { continue; } try { const entry = JSON.parse(line); // Only extract package entries; manifest also contains "slice", "path", and "content" entries if (entry.kind === "package") { // Validate required fields exist before creating package object if (!entry.name || !entry.version || !entry.sha256 || !entry.arch) { debug(`Skipping package entry with missing required fields: ${JSON.stringify(entry)}`); continue; } packages.push({ kind: entry.kind, name: entry.name, version: entry.version, sha256: entry.sha256, arch: entry.arch, }); } } catch (parseError) { // Skip malformed JSON lines - manifest may be corrupted or have trailing newlines debug(`Failed to parse Chisel manifest line: ${parseError instanceof Error ? parseError.message : String(parseError)}`); continue; } } debug(`Found ${packages.length} Chisel packages in manifest`); return packages; } catch (error) { debug(`Failed to process Chisel manifest: ${error instanceof Error ? error.message : String(error)}`); return []; } } exports.getChiselManifestContent = getChiselManifestContent; //# sourceMappingURL=static.js.map