Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 22 additions & 7 deletions src/malwareMatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ import path from "path";
import zlib from "zlib";
import * as semver from "semver";

// Type alias to improve readability for complex package shape
type PkgLike = {
purl?: string;
externalRefs?: Array<{ referenceType?: string; referenceLocator?: string }>;
name?: string;
version?: string;
versionInfo?: string;
};

const our_tool_name = "SBOM Toolkit";
const our_tool_url = "https://github.com/advanced-security/github-sbom-toolkit";

Expand All @@ -23,6 +32,12 @@ export interface MalwareMatch {
reason: string;
}

// Type alias for packages used in enumeratePackages
export type EnumeratedPackage = SbomPackage & {
externalRefs?: { referenceType?: string; referenceLocator?: string }[];
versionInfo?: string;
};

// Map GitHub ecosystem enums to purl types
const ecosystemToPurlType: Record<string, string> = {
ACTIONS: "githubactions",
Expand Down Expand Up @@ -112,11 +127,11 @@ export function matchMalware(advisories: MalwareAdvisoryNode[], sboms: Repositor
const index = new Map<string, MalwareAdvisoryNode[]>();
for (const adv of advisories) {
// Ignore advisories that have been withdrawn
if ((adv as unknown as { withdrawnAt?: string | null }).withdrawnAt) continue;
if (adv.withdrawnAt) continue;
// Ignore advisories older than cutoff (must be before cutoff in BOTH publishedAt & updatedAt to be excluded)
if (cutoffDate) {
const pub = new Date((adv as unknown as { publishedAt?: string }).publishedAt || 0);
const upd = new Date((adv as unknown as { updatedAt?: string }).updatedAt || 0);
const pub = new Date(adv.publishedAt || 0);
const upd = new Date(adv.updatedAt || 0);
if (pub < cutoffDate && upd < cutoffDate) continue;
}
for (const vuln of adv.vulnerabilities) {
Expand All @@ -131,12 +146,12 @@ export function matchMalware(advisories: MalwareAdvisoryNode[], sboms: Repositor
}

// Helper to enumerate packages with fallback to raw SPDX packages inside repoSbom.sbom if flattened list empty
const enumeratePackages = (repo: RepositorySbom): Array<SbomPackage & { externalRefs?: { referenceType?: string; referenceLocator?: string }[]; versionInfo?: string }> => {
const enumeratePackages = (repo: RepositorySbom): EnumeratedPackage[] => {
const explicit: SbomPackage[] = Array.isArray(repo.packages) ? repo.packages : [];
if (explicit.length > 0) return explicit as Array<SbomPackage & { externalRefs?: { referenceType?: string; referenceLocator?: string }[]; versionInfo?: string }>;
if (explicit.length > 0) return explicit as EnumeratedPackage[];
const rawMaybe: unknown = repo.sbom?.packages;
if (Array.isArray(rawMaybe)) {
return rawMaybe as Array<SbomPackage & { externalRefs?: { referenceType?: string; referenceLocator?: string }[]; versionInfo?: string }>;
return rawMaybe as EnumeratedPackage[];
}
return [];
};
Expand All @@ -146,7 +161,7 @@ export function matchMalware(advisories: MalwareAdvisoryNode[], sboms: Repositor
if (!pkgs.length) continue;

for (const pkg of pkgs) {
const pkgAny = pkg as unknown as { purl?: string; externalRefs?: Array<{ referenceType?: string; referenceLocator?: string }>; name?: string; version?: string; versionInfo?: string };
const pkgAny = pkg as unknown as PkgLike;
const candidatePurls = new Set<string>();
if (pkgAny.purl) candidatePurls.add(pkgAny.purl);
if (Array.isArray(pkgAny.externalRefs)) {
Expand Down