Skip to content

Instantly share code, notes, and snippets.

@MaZderMind
Last active February 25, 2024 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MaZderMind/bf704442bf3e0ac905e3ad5bc96f4100 to your computer and use it in GitHub Desktop.
Save MaZderMind/bf704442bf3e0ac905e3ad5bc96f4100 to your computer and use it in GitHub Desktop.
Atlassian Vulnerabilitiey API Interpretation code
import { parse, valid } from "semver";
type Status = "AFFECTED" | "FIXED"
function isVulnerable(selectedVersion: string, versions: [string, Status][]) {
return isFilterSelected(selectedVersion, versions) || checkVersionAffected(selectedVersion, versions);
}
function isFilterSelected(selectedVersion: string, versions: [string, Status][]) {
return versions
.filter(v => v[1] === "AFFECTED")
// Get a list of the versions from the CVE and check if they exist in the filtered version
.map(a => a[0])
.includes(selectedVersion);
}
// takes a version and checks if it is within the ranges of a list of fixed versions (sorted from lowest to highest)
// returns true if not within the fixed versions (therefore it's a vulnerable/affected version)
// returns false otherwise
function checkVersionAffected(selectedVersion: string, versions: [string, Status][]): boolean {
let version = parse(selectedVersion);
let parsedFixedVersion = versions
.filter(v => v[1] === "FIXED")
.map(v => parse(v[0]))
.filter(v => v != null)
.sort((a, b) => compareSemanticVersions(String(a), String(b)));
let parsedIntroducedVersion = versions
.filter(v => v[1] === "AFFECTED")
.map(v => parse(v[0]))
.filter(v => v != null)
.sort((a, b) => compareSemanticVersions(String(a), String(b)));
if (version == null) {
return false;
}
for (let i = 0; i < parsedFixedVersion.length; i++) {
// only compare patch version ranges if the version's major & minor values are the same as any fixed version
if (version.major === parsedFixedVersion[i]?.major && version.minor === parsedFixedVersion[i]?.minor) {
if (parsedFixedVersion[i]?.patch !== undefined && version.patch >= (parsedFixedVersion[i]?.patch || 0)) {
return false;
} else {
return true;
}
}
// only compare minor version ranges if the version's major values are the same as any fixed version
if (version.major === parsedFixedVersion[i]?.major) {
if (parsedFixedVersion[i]?.minor !== undefined && version.minor >= (parsedFixedVersion[i]?.minor || 0)) {
return false;
} else {
return true;
}
}
}
// any version outside of the latest fixed version range isn't affected
if (
parsedFixedVersion[parsedFixedVersion.length - 1]?.major !== undefined &&
version.major > (parsedFixedVersion[parsedFixedVersion.length - 1]?.major || 0)
) {
return false;
}
// any version under the earliest fixed version and still in the introduced version is affected
if (
parsedFixedVersion[0]?.major !== undefined &&
parsedIntroducedVersion[0]?.major !== undefined &&
version.major < parsedFixedVersion[0]?.major &&
version.major >= parsedIntroducedVersion[0]?.major
) {
return true;
}
return false;
}
function compareSemanticVersions(a: string, b: string) {
// 1. Split the strings into their parts.
const a1 = a.split(".");
const b1 = b.split(".");
// 2. Contingency in case there's a 4th or 5th version
const len = Math.min(a1.length, b1.length);
// 3. Look through each version number and compare.
for (let i = 0; i < len; i++) {
const a2 = +a1[i] || 0;
const b2 = +b1[i] || 0;
if (a2 !== b2) {
return a2 > b2 ? 1 : -1;
}
}
// 4. We hit this if the all checked versions so far are equal
return b1.length - a1.length;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment