Module: StillActive::PoisonSecurityCorrelator

Extended by:
PoisonSecurityCorrelator
Included in:
PoisonSecurityCorrelator
Defined in:
lib/still_active/poison_security_correlator.rb

Overview

Whole-tree correlation, run once after the fan-out: a poison cap is far more urgent when the dependency it pins is ITSELF vulnerable in the same tree -- "a dormant package is holding you on a known-vulnerable dependency, below the version that fixes it." Both facts are already assembled (the poison constraints and every dependency's vulnerability count), so this is one pass, no extra fetches. It marks the security-relevant caps so the report can lead with them and demote the FYI caps on healthy dependencies.

The moat's strongest case (verified on real repos): several archived Google client libraries pin a vulnerable protobuf three majors below the fix.

Constant Summary collapse

SECURITY_THRESHOLD =

Only a HIGH-or-above advisory on the capped dep makes the cap security- relevant. Most advisories are low-threat noise (research: ~95% of vulnerable deps are unreachable/low-impact), so a low/medium CVE on the pinned dep isn't the "you're stuck below the fix" story. Unscored advisories fail CLOSED (a confirmed advisory we can't score could be severe), matching --fail-if- vulnerable. Reachability/exploitability is beyond static, metadata-only sight and deliberately out of scope -- this gates on severity, not exploitability.

"high"
BELOW_FIX_LABELS =

The severity labels that let an advisory establish "below the fix". Only a confirmed HIGH+ advisory with a known fix can: an unscored advisory (which the capped_dep_vulnerable gate accepts fail-closed) has no reliable fix analysis.

["high", "critical"].freeze

Instance Method Summary collapse

Instance Method Details

#correlate(result_object) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/still_active/poison_security_correlator.rb', line 35

def correlate(result_object)
  advisories = flat_advisories(result_object)
  copies = copy_index(result_object)

  result_object.each_value do |data|
    # FLAT (rubygems/pypi): mark below-fix on the poison caps already attached.
    mark_flat_constraints(data, advisories)
    # NESTED (npm/cargo): promote a genuine below-fix candidate into :constraints.
    promote_nested_below_fix(data, copies) if data[:capped_deps]

    constraints = hashes(data[:constraints])
    next if constraints.empty?

    data[:poison_security_relevant] = true if constraints.any? { |c| c[:capped_dep_vulnerable] }
    data[:poison_below_fix] = true if constraints.any? { |c| c[:capped_below_fix] }
  end
end