File Explorer

/proc/thread-self/root/var/lang/lib/node_modules/npm/node_modules/@npmcli/arborist/lib

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

vuln.js6.0 KB · 219 lines
// An object representing a vulnerability either as the result of an// advisory or due to the package in question depending exclusively on// vulnerable versions of a dep.//// - name: package name// - range: Set of vulnerable versions// - nodes: Set of nodes affected// - effects: Set of vulns triggered by this one// - advisories: Set of advisories (including metavulns) causing this vuln.//   All of the entries in via are vulnerability objects returned by//   @npmcli/metavuln-calculator// - via: dependency vulns which cause this one const { satisfies, simplifyRange } = require('semver')const semverOpt = { loose: true, includePrerelease: true } const localeCompare = require('@isaacs/string-locale-compare')('en')const npa = require('npm-package-arg') const severities = new Map([  ['info', 0], [0, 'info'],  ['low', 1], [1, 'low'],  ['moderate', 2], [2, 'moderate'],  ['high', 3], [3, 'high'],  ['critical', 4], [4, 'critical'],  [null, -1], [-1, null],]) class Vuln {  #range = null  #simpleRange = null  // assume a fix is available unless it hits a top node  // that locks it in place, setting this false or {isSemVerMajor, version}.  #fixAvailable = true   constructor ({ name, advisory }) {    this.name = name    this.via = new Set()    this.advisories = new Set()    this.severity = null    this.effects = new Set()    this.topNodes = new Set()    this.nodes = new Set()    this.fixBlockedByReleaseAge = false    this.addAdvisory(advisory)    this.packument = advisory.packument    this.versions = advisory.versions  }   get fixAvailable () {    return this.#fixAvailable  }   set fixAvailable (f) {    this.#fixAvailable = f    // if there's a fix available for this at the top level, it means that    // it will also fix the vulns that led to it being there.  to get there,    // we set the vias to the most "strict" of fix availables.    // - false: no fix is available    // - {name, version, isSemVerMajor} fix requires -f, is semver major    // - {name, version} fix requires -f, not semver major    // - true: fix does not require -f    // TODO: duped entries may require different fixes but the current    // structure does not support this, so the case were a top level fix    // corrects a duped entry may mean you have to run fix more than once    for (const v of this.via) {      // don't blow up on loops      if (v.fixAvailable === f) {        continue      }       if (f === false) {        v.fixAvailable = f      } else if (v.fixAvailable === true) {        v.fixAvailable = f      } else if (typeof f === 'object' && (        typeof v.fixAvailable !== 'object' || !v.fixAvailable.isSemVerMajor)) {        v.fixAvailable = f      }    }  }   get isDirect () {    for (const node of this.nodes.values()) {      for (const edge of node.edgesIn) {        if (edge.from.isProjectRoot || edge.from.isWorkspace) {          return true        }      }    }    return false  }   testSpec (spec) {    const specObj = npa(spec)    if (!specObj.registry) {      return true    }     if (specObj.subSpec) {      spec = specObj.subSpec.rawSpec    }     for (const v of this.versions) {      if (satisfies(v, spec) && !satisfies(v, this.range, semverOpt)) {        return false      }    }    return true  }   toJSON () {    return {      name: this.name,      severity: this.severity,      isDirect: this.isDirect,      // just loop over the advisories, since via is only Vuln objects,      // and calculated advisories have all the info we need      via: [...this.advisories].map(v => v.type === 'metavuln' ? v.dependency : {        ...v,        versions: undefined,        vulnerableVersions: undefined,        id: undefined,      }).sort((a, b) =>        localeCompare(String(a.source || a), String(b.source || b))),      effects: [...this.effects].map(v => v.name).sort(localeCompare),      range: this.simpleRange,      nodes: [...this.nodes].map(n => n.location).sort(localeCompare),      fixAvailable: this.#fixAvailable,      ...(this.fixBlockedByReleaseAge        ? { fixBlockedByReleaseAge: this.fixBlockedByReleaseAge }        : {}),    }  }   addVia (v) {    this.via.add(v)    v.effects.add(this)    // call the setter since we might add vias _after_ setting fixAvailable    this.fixAvailable = this.fixAvailable  }   deleteVia (v) {    this.via.delete(v)    v.effects.delete(this)  }   deleteAdvisory (advisory) {    this.advisories.delete(advisory)    // make sure we have the max severity of all the vulns causing this one    this.severity = null    this.#range = null    this.#simpleRange = null    // refresh severity    for (const advisory of this.advisories) {      this.addAdvisory(advisory)    }     // remove any effects that are no longer relevant    const vias = new Set([...this.advisories].map(a => a.dependency))    for (const via of this.via) {      if (!vias.has(via.name)) {        this.deleteVia(via)      }    }  }   addAdvisory (advisory) {    this.advisories.add(advisory)    const sev = severities.get(advisory.severity)    this.#range = null    this.#simpleRange = null    if (sev > severities.get(this.severity)) {      this.severity = advisory.severity    }  }   get range () {    if (!this.#range) {      this.#range = [...this.advisories].map(v => v.range).join(' || ')    }    return this.#range  }   get simpleRange () {    if (this.#simpleRange && this.#simpleRange === this.#range) {      return this.#simpleRange    }     const versions = [...this.advisories][0].versions    const range = this.range    this.#simpleRange = simplifyRange(versions, range, semverOpt)    this.#range = this.#simpleRange    return this.#simpleRange  }   isVulnerable (node) {    if (this.nodes.has(node)) {      return true    }     const { version } = node.package    if (!version) {      return false    }     for (const v of this.advisories) {      if (v.testVersion(version)) {        this.nodes.add(node)        return true      }    }     return false  }} module.exports = Vuln