From sonarcloud-security-updating
Analyze GitHub Dependabot dependency vulnerability alerts and suggest triage decisions (dismiss/fix/escalate) with explanations. Use when the user needs help reviewing Dependabot alerts, deciding whether dependencies are exploitable, or triaging CVEs across NASA PDS repositories.
How this skill is triggered — by the user, by Claude, or both
Slash command
/sonarcloud-security-updating:dependabot-alerts-triagingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill helps you make informed triage decisions on GitHub Dependabot dependency vulnerability alerts by analyzing each CVE — **one at a time** — in the context of how the affected package is actually used in NASA-PDS code. You review and approve every decision before anything is recorded or applied.
This skill helps you make informed triage decisions on GitHub Dependabot dependency vulnerability alerts by analyzing each CVE — one at a time — in the context of how the affected package is actually used in NASA-PDS code. You review and approve every decision before anything is recorded or applied.
dependabot-alerts-exporting skillgh CLI authenticated (for creating outlaw-tracker issues)1. dependabot-alerts-exporting → Export alerts to JSON
2. dependabot-alerts-triaging → THIS SKILL: Analyze & decide one by one
3. dismiss-alerts.mjs → Apply dismissal decisions to GitHub
| Action | When to Use | GitHub API Value |
|---|---|---|
| fix | Patched version available; upgrade is feasible | Keep open, create outlaw-tracker issue |
| tolerable_risk | Real CVE but attack vector doesn't apply to PDS usage | tolerable_risk |
| inaccurate | CVE doesn't affect this package/version, or vulnerable function is never called | inaccurate |
| no_bandwidth | Real issue, acceptable risk for now, defer to backlog | no_bandwidth |
Ask the user for the path to their Dependabot alerts JSON file. Parse it and show a brief summary:
Loaded 5 alerts for nasa-pds/registry-legacy-solr
HIGH: 1
MEDIUM: 3
LOW: 1
I'll go through each one individually, starting with the highest severity.
Ready? [yes]
Wait for the user to confirm before starting.
Before presenting any alerts, identify the unique repositories in the export and clone them into /tmp. A local clone enables fast grep searches across all source files — much faster and more thorough than the GitHub Search API, which is rate-limited and only indexes certain file types.
# Get unique repos from the export
jq -r '[.alerts[].repository] | unique[]' alerts.json
# Shallow-clone each one
git clone --depth=1 https://github.com/NASA-PDS/<repo>.git /tmp/<repo>
After cloning, check for a CLAUDE.md in each repo — it often contains architecture notes, production deployment details, known breaking-change warnings, and dependency constraints that directly inform triage decisions:
cat /tmp/<repo>/CLAUDE.md 2>/dev/null || echo "No CLAUDE.md"
Read and internalize this context before starting the alert-by-alert triage.
Sort alerts: CRITICAL → HIGH → MEDIUM → LOW. Within the same severity, sort by CVSS score descending.
If the same CVE appears in multiple repos, note it when presenting the first instance ("This CVE also affects 2 other repos — after you decide here, I can apply the same decision to those"). Present each repo's alert individually — never assume the same decision applies without the user confirming.
Present one alert using this format, then stop and wait:
Alert #1/5 — nasa-pds/registry-legacy-solr — Alert #33
────────────────────────────────────────────────────────
Package: lxml (pip)
Severity: HIGH — CVSS 7.5
CVE: CVE-2026-41066
Advisory: https://github.com/advisories/GHSA-xxxx-xxxx-xxxx
Alert URL: https://github.com/NASA-PDS/registry-legacy-solr/security/dependabot/33
Vulnerable: < 6.1.0 | Fixed: 6.1.0
Manifest: src/main/resources/requirements.txt (runtime)
WHAT IS IT:
lxml's iterparse() and ETCompatXMLParser() use a default libxml2 configuration
that allows XML External Entity (XXE) processing. If untrusted XML is passed to
these functions, an attacker can read arbitrary local files or trigger SSRF.
WHAT I FOUND IN THE REPO:
[Search the repo for lxml imports and usages. Report specifically:
- Which functions are called (parse, iterparse, fromstring, etc.)
- Whether the input comes from user-supplied data or internal sources
- E.g.: "lxml.etree.parse() is called on PDS4 labels in src/harvest/xml_parser.py.
Labels are submitted by external users — XXE is reachable."]
EXPLOITABILITY:
[Based on the code findings, assess whether the vulnerable API is reachable
with attacker-controlled input. Be specific.
E.g.: "HIGH — external XML is parsed without disabling entity resolution."]
MY RECOMMENDATION:
Action: fix
Reason: Patch available (6.1.0). Runtime dep. Likely reachable with external XML.
Comment: "CVE-2026-41066: lxml XXE via iterparse(). Upgrade to >=6.1.0.
— Triaged with assistance from Claude"
Confidence: medium (awaiting code confirmation)
outlaw-tracker: YES
Do you want to:
1. ✅ Fix — keep open + create outlaw-tracker issue
2. 🟡 Dismiss — tolerable_risk (attack vector not applicable to PDS)
3. 🟡 Dismiss — inaccurate (vulnerable function not used / CVE doesn't apply)
4. 🟡 Dismiss — no_bandwidth (real issue, defer)
5. 🔍 Investigate more first
6. ⏭️ Skip for now
Do not present the next alert until the user responds to this one.
If the user picks option 5 (investigate more), search the repository using available tools:
After the user responds, immediately update the triage field for that alert in the working JSON and confirm:
✅ Recorded: dismiss (inaccurate) — lxml is only used via lxml.etree.fromstring() on
internally-generated XML, not user input. Vulnerable iterparse() is never called.
Progress: 1/5 done — 4 remaining
Fill the triage object:
{
"triage": {
"action": "dismiss",
"dismissedReason": "inaccurate",
"comment": "lxml.iterparse() is never called in this repo. Only fromstring() is used on internally-generated XML. — Triaged with assistance from Claude",
"githubIssueUrl": null,
"reviewer": "jordanpadams",
"triageDate": "2026-04-23T15:30:00Z",
"confidence": "high"
}
}
Valid dismissedReason values (GitHub API):
tolerable_risk — Risk is real but acceptable in PDS contextinaccurate — CVE doesn't apply (wrong function, version confusion, not used)no_bandwidth — Real issue, low priority, deferredWhen the user approves fix, immediately create a GitHub issue before moving to the next alert. Write the body to /tmp/dependabot_issue_body.md using the Write tool, then:
gh issue create \
--repo NASA-PDS/outlaw-tracker \
--title "CVE-YYYY-NNNNN: <package> vulnerability in NASA-PDS/<repo>" \
--label "security" \
--body-file /tmp/dependabot_issue_body.md
Issue body must include:
pip install "lxml>=6.1.0")Record the returned issue URL in triage.githubIssueUrl. Confirm the issue was created, then immediately advance to the next alert.
All comments must end with:
— Triaged with assistance from Claude
After recording a decision (and creating any outlaw-tracker issue), present the next alert using the same Step 3 format. Repeat until all alerts are done or the user says stop.
Maintain two metric files throughout the session, updating them immediately after each alert decision. Do not wait until the end.
dependabot-triage-metrics.json — structured data for programmatic access:
{
"triageSession": {
"startDate": "2026-04-23T15:00:00Z",
"organization": "nasa-pds",
"totalRepositoriesScanned": 1,
"totalAlertsExported": 5,
"bySeverity": { "critical": 0, "high": 1, "medium": 3, "low": 1 },
"repositoriesTriaged": 0,
"alertsTriaged": 0,
"alertsRemaining": 5,
"tokenUsage": {
"total": 0,
"notes": "Update after each repository — check Claude Code token counter"
}
},
"remediationSummary": {
"fix": 0,
"tolerable_risk": 0,
"inaccurate": 0,
"no_bandwidth": 0,
"skipped": 0,
"outlaw_tracker_issues_created": 0
},
"repositoryDetails": []
}
DEPENDABOT_TRIAGE_METRICS.md — human-readable dashboard:
# Dependabot Triage Metrics
**Session Date:** 2026-04-23
**Organization:** nasa-pds
**Status:** In Progress
---
## 📊 Overall Statistics
| Metric | Count |
|--------|-------|
| **Total Repositories Scanned** | 1 |
| **Total Alerts Exported** | 5 |
| ├─ Critical | 0 |
| ├─ High | 1 |
| ├─ Medium | 3 |
| └─ Low | 1 |
| **Alerts Triaged** | 0 |
| **Alerts Remaining** | 5 |
| **Token Usage** | 0 |
---
## 🎯 Remediation Summary
| Decision | Count | % |
|----------|-------|---|
| **fix** | 0 | 0% |
| **tolerable_risk** | 0 | 0% |
| **inaccurate** | 0 | 0% |
| **no_bandwidth** | 0 | 0% |
| **outlaw-tracker Issues Created** | 0 | — |
---
## 📁 Repository Details
_(none yet)_
---
_Last Updated: 2026-04-23T15:00:00Z_
After recording each alert's decision:
alertsTriaged and decrement alertsRemainingremediationSummary counterfix, increment outlaw_tracker_issues_created and record the URLrepositoryDetails[]DEPENDABOT_TRIAGE_METRICS.mdtriageSession.tokenUsage.total{
"repository": "nasa-pds/registry-legacy-solr",
"triagedDate": "2026-04-23T15:30:00Z",
"totalAlerts": 5,
"bySeverity": { "high": 1, "medium": 3, "low": 1 },
"decisions": {
"fix": 1,
"inaccurate": 1,
"no_bandwidth": 2,
"tolerable_risk": 1
},
"outlaw_tracker_issues": [
{
"issueNumber": 22,
"url": "https://github.com/NASA-PDS/outlaw-tracker/issues/22",
"title": "CVE-2026-25645: requests vulnerability in NASA-PDS/registry-legacy-solr",
"relatedAlerts": [29]
}
],
"alertDetails": [
{
"alertNumber": 33,
"package": "lxml",
"severity": "high",
"cveId": "CVE-2026-41066",
"decision": "inaccurate",
"rationale": "lxml never imported or used in codebase"
}
]
}
When all alerts are triaged (or the user types "done"/"save"), show a final summary and write the updated JSON:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Triage Complete — nasa-pds/registry-legacy-solr
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Total: 5
fix: 1 → outlaw-tracker issues: #22
inaccurate: 1
tolerable_risk: 1
no_bandwidth: 2
skipped: 0
Saved:
dependabot-registry-legacy-solr-triaged.json
dependabot-triage-metrics.json
DEPENDABOT_TRIAGE_METRICS.md
Next — apply dismissals:
node scripts/dismiss-alerts.mjs dependabot-registry-legacy-solr-triaged.json --dry-run
Write the updated alerts JSON appending -triaged before .json.
Offer to run the dismissal script after saving:
# Preview first
node scripts/dismiss-alerts.mjs dependabot-alerts-triaged.json --dry-run
# Apply
node scripts/dismiss-alerts.mjs dependabot-alerts-triaged.json
The script PATCHes each alert where triage.action === "dismiss" via the GitHub API with the recorded dismissedReason and comment. Requires GITHUB_TOKEN (same as the export step).
After dismissals are applied, commit the triage artifacts to NASA-PDS/outlaw-tracker and open a pull request so the session is permanently recorded and reviewable.
dependabot-alerts-triaged.json — full alert data with triage decisionsdependabot-triage-metrics.json — structured session metricsDEPENDABOT_TRIAGE_METRICS.md — human-readable dashboard# 1. Detect whether we're already inside the outlaw-tracker repo
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
REMOTE=$(git remote get-url origin 2>/dev/null)
if echo "$REMOTE" | grep -q "outlaw-tracker"; then
# Already in the repo — use it directly
OUTLAW_DIR="$REPO_ROOT"
else
# Clone it
git clone --depth=1 https://github.com/NASA-PDS/outlaw-tracker.git /tmp/outlaw-tracker
OUTLAW_DIR="/tmp/outlaw-tracker"
fi
cd "$OUTLAW_DIR"
# 2. Create a branch named for the session date and scope
BRANCH="dependabot-triage-$(date +%Y%m%d)"
git checkout -b "$BRANCH"
# 3. Create the triage-reports directory structure
REPORT_DIR="triage-reports/dependabot/$(date +%Y%m%d)"
mkdir -p "$REPORT_DIR"
# 4. Copy triage artifacts into the report directory
cp /path/to/dependabot-alerts-triaged.json "$REPORT_DIR/"
cp /path/to/dependabot-triage-metrics.json "$REPORT_DIR/"
cp /path/to/DEPENDABOT_TRIAGE_METRICS.md "$REPORT_DIR/"
# 5. Commit
git add "$REPORT_DIR"
git commit -m "Add Dependabot triage results for nasa-pds (<date>)
Triaged <N> alerts across <M> repositories.
fix: <N> (outlaw-tracker issues created: <N>)
inaccurate: <N>
tolerable_risk: <N>
no_bandwidth: <N>
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>"
# 6. Push
git push -u origin "$BRANCH"
Write the PR body to /tmp/triage_pr_body.md using the Write tool, then create the PR:
gh pr create \
--repo NASA-PDS/outlaw-tracker \
--base main \
--head "$BRANCH" \
--title "Dependabot triage results — nasa-pds (<date>)" \
--body-file /tmp/triage_pr_body.md \
--label "security"
The PR body should include:
## Summary
Dependabot triage session for `nasa-pds` organization on <date>.
| Metric | Count |
|--------|-------|
| Repositories triaged | <N> |
| Total alerts | <N> |
| fix | <N> |
| inaccurate | <N> |
| tolerable_risk | <N> |
| no_bandwidth | <N> |
| outlaw-tracker issues created | <N> |
| Token usage | <N> |
## outlaw-tracker Issues Created
- #<N> — CVE-XXXX-XXXXX: <package> in <repo>
## Repositories Triaged
- `nasa-pds/<repo>` — <N> alerts (<N> fix, <N> dismissed)
## Artifacts
- `triage-reports/dependabot/<date>/dependabot-alerts-triaged.json`
- `triage-reports/dependabot/<date>/dependabot-triage-metrics.json`
- `triage-reports/dependabot/<date>/DEPENDABOT_TRIAGE_METRICS.md`
Dismissals have been applied to GitHub via the Dependabot API.
— Triaged with assistance from Claude
inaccurate — not used
devDependencies / requirements-dev.txt, not in the production artifacttolerable_risk
inaccurate — version or advisory mismatch
no_bandwidth
no_bandwidth and tolerable_risk are more likely appropriate; call this out explicitlyProvides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.
npx claudepluginhub riverma/pds-agent-marketplace --plugin creating-pds-issues