refactor(ci): extract shared exploitability enrichment helper (#95)

* refactor(ci): share exploitability enrichment script

* refactor(scripts): reuse shared exploitability enricher in local feed
This commit is contained in:
davida-ps
2026-03-01 21:50:10 +02:00
committed by GitHub
parent 56a36b7e52
commit e0eae65586
4 changed files with 283 additions and 193 deletions
+6 -53
View File
@@ -206,60 +206,13 @@ jobs:
echo "=== Analyzing exploitability for community advisory ==="
# Extract fields from advisory for analysis
CVE_ID=$(jq -r '.id' tmp_advisory.json)
SEVERITY=$(jq -r '.severity // "medium"' tmp_advisory.json)
VULN_TYPE=$(jq -r '.type // "unknown"' tmp_advisory.json)
DESCRIPTION=$(jq -r '.description // ""' tmp_advisory.json)
REFERENCES=$(jq -c '.references // []' tmp_advisory.json)
scripts/ci/enrich_exploitability.sh \
--mode single \
--input tmp_advisory.json \
--output tmp_advisory.json
# Map severity to approximate CVSS score for analysis
case "$SEVERITY" in
critical) CVSS_SCORE=9.5 ;;
high) CVSS_SCORE=7.5 ;;
medium) CVSS_SCORE=5.5 ;;
low) CVSS_SCORE=3.0 ;;
*) CVSS_SCORE=5.0 ;;
esac
# Build input JSON for analyzer
INPUT_JSON=$(jq -n \
--arg cve_id "$CVE_ID" \
--argjson cvss_score "$CVSS_SCORE" \
--arg type "$VULN_TYPE" \
--arg description "$DESCRIPTION" \
--argjson references "$REFERENCES" \
'{
cve_id: $cve_id,
cvss_score: $cvss_score,
type: $type,
description: $description,
references: $references
}')
# Run exploitability analysis with exploit detection.
# Continue without enrichment if analysis fails.
if ANALYSIS=$(echo "$INPUT_JSON" | python utils/analyze_exploitability.py --json --check-exploits 2>/dev/null); then
echo "$ANALYSIS" > tmp_exploitability.json
echo "✓ Analyzed $CVE_ID"
# Merge exploitability analysis into advisory
jq --slurpfile analysis tmp_exploitability.json '
. + {
exploitability_score: $analysis[0].exploitability_score,
exploitability_rationale: $analysis[0].exploitability_rationale,
attack_vector_analysis: $analysis[0].attack_vector_analysis,
exploit_detection: $analysis[0].exploit_detection
}
' tmp_advisory.json > tmp_advisory_enriched.json
mv tmp_advisory_enriched.json tmp_advisory.json
echo "=== Exploitability analysis complete ==="
echo "Exploitability score: $(jq -r '.exploitability_score // "unknown"' tmp_advisory.json)"
else
echo "::warning::Failed to analyze exploitability for $CVE_ID, continuing without enrichment"
fi
echo "=== Exploitability analysis complete ==="
echo "Exploitability score: $(jq -r '.exploitability_score // "unknown"' tmp_advisory.json)"
- name: Update feed
if: steps.parse.outputs.already_exists != 'true'
+5 -62
View File
@@ -684,68 +684,11 @@ jobs:
}] | map({(.id): .cvss_vector}) | add
' tmp/filtered_cves.json > tmp/cvss_vectors.json
# Process each advisory through exploitability analyzer
jq -c '.[]' tmp/new_advisories.json | while IFS= read -r advisory; do
CVE_ID=$(echo "$advisory" | jq -r '.id')
CVSS_SCORE=$(echo "$advisory" | jq -r '.cvss_score // 0')
CVSS_VECTOR=$(jq -r --arg id "$CVE_ID" '.[$id] // ""' tmp/cvss_vectors.json)
VULN_TYPE=$(echo "$advisory" | jq -r '.type // ""')
DESCRIPTION=$(echo "$advisory" | jq -r '.description // ""')
REFERENCES=$(echo "$advisory" | jq -c '.references // []')
# Build input JSON for analyzer
INPUT_JSON=$(jq -n \
--arg cve_id "$CVE_ID" \
--argjson cvss_score "$CVSS_SCORE" \
--arg cvss_vector "$CVSS_VECTOR" \
--arg type "$VULN_TYPE" \
--arg description "$DESCRIPTION" \
--argjson references "$REFERENCES" \
'{
cve_id: $cve_id,
cvss_score: $cvss_score,
cvss_vector: $cvss_vector,
type: $type,
description: $description,
references: $references
}')
# Run exploitability analysis with exploit detection.
# Keep processing if any single advisory analysis fails.
if ANALYSIS=$(echo "$INPUT_JSON" | python utils/analyze_exploitability.py --json --check-exploits 2>/dev/null); then
echo "$ANALYSIS" > "tmp/exploitability_${CVE_ID}.json"
echo "✓ Analyzed $CVE_ID"
else
echo "::warning::Failed to analyze exploitability for $CVE_ID, skipping enrichment"
fi
done
# Merge exploitability analysis back into advisories.
if ls tmp/exploitability_*.json >/dev/null 2>&1; then
jq -s '.' tmp/exploitability_*.json > tmp/exploitability_analyses.json
else
echo '[]' > tmp/exploitability_analyses.json
fi
jq --slurpfile analyses tmp/exploitability_analyses.json '
map(
. as $advisory |
($analyses[0] | map(select(.cve_id == $advisory.id)) | first) as $analysis |
if $analysis then
$advisory + {
exploitability_score: $analysis.exploitability_score,
exploitability_rationale: $analysis.exploitability_rationale,
attack_vector_analysis: $analysis.attack_vector_analysis,
exploit_detection: $analysis.exploit_detection
}
else
$advisory
end
)
' tmp/new_advisories.json > tmp/new_advisories_enriched.json
# Replace original with enriched version
mv tmp/new_advisories_enriched.json tmp/new_advisories.json
scripts/ci/enrich_exploitability.sh \
--mode batch \
--input tmp/new_advisories.json \
--output tmp/new_advisories.json \
--cvss-vectors tmp/cvss_vectors.json
echo "=== Exploitability analysis complete ==="