Terminal.skills
Use Cases/Set Up Automated Dependency Vulnerability Remediation with AI

Set Up Automated Dependency Vulnerability Remediation with AI

Automatically detect, prioritize, and fix dependency vulnerabilities with AI-generated patches and upgrade paths.

Development#coding-agent#automation#sub-agent#background-process#orchestration
Works with:claude-codeopenai-codexgemini-clicursor
$

The Problem

Priya's 20-person SaaS startup has 340 npm dependencies across three services. Dependabot opens PRs dutifully, but nobody has time to review them. Right now, 47 security PRs sit open -- some months old. The team cannot tell which vulnerabilities are actually exploitable in their codebase versus theoretical risks buried in transitive dependencies they never call.

A recent penetration test made it worse: two critical CVEs were flagged, and both had open Dependabot PRs sitting unreviewed for 11 weeks. The auditors were not impressed. To make matters harder, the last time someone tried to merge a major dependency update, it broke the build and took half a day to untangle. Now everyone is afraid to touch security PRs at all.

The result is a backlog that grows faster than the team can review it, with no way to distinguish between "this could get us hacked tomorrow" and "this is a theoretical risk in a library we never import."

The Solution

Using the security-audit, coding-agent, and github skills, this walkthrough triages all 47 open vulnerabilities by actual exploitability, generates safe upgrade patches with necessary code changes for the ones that matter, and sets up a weekly automation that prevents the backlog from returning.

Step-by-Step Walkthrough

Step 1: Triage by Reachability

The key insight that changes everything: a critical CVE in code your application never calls is less dangerous than a moderate CVE in your hot path. Dependabot does not know this -- it treats every vulnerability the same. The first step separates real risks from noise:

Run a security audit on our three services in ./api, ./web, and ./worker. For each vulnerability, determine: severity, whether the vulnerable code path is actually reachable in our codebase, and the upgrade path (is it a patch bump or a major version change?).

Of the 47 open vulnerabilities, the triage breaks down like this:

CRITICAL -- exploitable, fix immediately:

CVEPackageWhere It's Reachable
CVE-2024-4367pdf.js RCEDirect call in ./worker/pdf-parser.js
CVE-2024-29041express path traversalReachable via file upload route

HIGH -- exploitable, fix this sprint:

CVEPackageWhere It's Reachable
CVE-2024-37890ws DoSWebSocket server in ./api/realtime.js
CVE-2024-28863tar arbitrary file writeUsed in backup restore flow

MEDIUM -- not directly exploitable, but safe to upgrade: 12 vulnerabilities, all patch-level bumps with no breaking changes.

LOW -- no reachable code path: 31 vulnerabilities where the vulnerable code exists in the dependency but the application never calls it. For example, a vulnerability in the XML parser of a library that the application only uses for JSON operations.

4 out of 47 are actually dangerous. The rest are either unreachable or safe patch bumps. This single triage step changes the remediation from "review 47 PRs" to "fix 4 real problems" -- a 91% reduction in work that also prioritizes what matters most.

The reachability analysis traces import chains from the application's entry points to the vulnerable function in each dependency. For the 31 low-priority items, it produces evidence like: "The vulnerable xml.parse() function in libxmljs is never called. Your application imports libxmljs only through cheerio, and cheerio only calls htmlParser2, which does not use the vulnerable XML path." This is the kind of analysis that would take a developer hours per vulnerability to do manually.

Step 2: Generate Safe Upgrade Patches

For the 4 exploitable vulnerabilities, Priya needs more than a version bump -- she needs to know what will break and how to fix it:

For the 2 critical and 2 high vulnerabilities, generate upgrade patches. For each, show what version to upgrade to, any breaking API changes, and the code modifications needed in our codebase to stay compatible.

Patch 1: pdf.js RCE (CVE-2024-4367)

This is the scariest one -- and the one that requires the most work. pdfjs-dist jumps from 3.4.120 to 4.2.67, a major version bump. The getDocument() API changed its return type, and the render method has a new signature that requires explicit canvas context options. Two files need updates in the worker service, and 3 new test cases cover the changed API surface:

json
{
  "pdfjs-dist": "3.4.120 -> 4.2.67 (major)",
  "files_modified": ["worker/pdf-parser.js", "worker/pdf-renderer.js"],
  "tests_added": "worker/__tests__/pdf-parser.test.js (3 cases)",
  "branch": "fix/cve-2024-4367-pdfjs"
}

This is exactly the kind of upgrade that the team was afraid of. But with the code changes already written and tested on the branch, the review is straightforward -- Priya can see exactly what changed and why.

Patch 2: express path traversal (CVE-2024-29041)

The easy one. Minor version bump from 4.18.2 to 4.21.0 with no breaking changes. All existing tests pass without modification.

json
{
  "express": "4.18.2 -> 4.21.0 (minor)",
  "files_modified": ["package.json", "package-lock.json"],
  "breaking_changes": "none",
  "branch": "fix/cve-2024-29041-express"
}

This Dependabot PR could have been merged 11 weeks ago with zero risk. It sat open because it looked the same as the scary pdf.js upgrade -- just another security PR in a wall of 47.

Patch 3: ws DoS (CVE-2024-37890)

Minor version bump from 8.13.0 to 8.17.1. No breaking changes, but the maxPayload default changed from 100 MB to 64 MB. The patch explicitly sets maxPayload in api/realtime.js to preserve existing behavior and avoid surprising WebSocket disconnections for users uploading large payloads.

Patch 4: tar arbitrary file write (CVE-2024-28863)

Minor version bump from 6.1.15 to 6.2.1. No breaking changes, no code modifications needed. The fix adds path validation during extraction to prevent directory traversal attacks -- an attacker could craft a tar file with ../../etc/passwd paths to write outside the extraction directory.

Each patch lives on its own branch with a clear PR description: the CVE number, a plain-English explanation of the vulnerability, the exact upgrade path, and what changed in the codebase. Ready for review and merge without any additional research.

Step 3: Clear the Backlog

Priya reviews and merges the 4 critical/high patches in one afternoon -- each branch has the dependency bump, the code changes, and the test updates already done. No half-day build breakage. The pdf.js major version upgrade, which would have been the most intimidating to tackle manually, takes 15 minutes to review because the code changes are isolated and tested.

The 12 medium-severity patch bumps get auto-merged after CI passes. No code changes needed, and the version bumps are all within the same major version.

The remaining 31 low-priority alerts are documented with justification: "vulnerable code path not reachable in our application, verified by static analysis of import chains." Each gets a suppression entry with an expiration date -- revisit in 90 days in case the codebase changes and the vulnerable path becomes reachable. The backlog goes from 47 open PRs to zero in a single afternoon.

Step 4: Prevent the Backlog from Returning

The one-time cleanup is only useful if the problem does not come back. Priya sets up weekly automation:

Create a GitHub Actions workflow that runs weekly: scans for new vulnerabilities, filters out unreachable code paths, and auto-creates PRs for patch-level fixes. For major version bumps, create an issue with an impact analysis instead.

The weekly workflow runs every Monday and handles three tiers automatically:

  • Patch bumps with no reachable vulnerability: auto-merged after CI passes. No human review needed.
  • Patch bumps with reachable vulnerability: PR created with a "security-fix" label and assigned to the team lead for fast-track review.
  • Major version bumps: GitHub issue created with a full impact analysis -- which files use the dependency, what API changes exist in the new version, and estimated effort to migrate.

Patch bumps never pile up again because they merge automatically. Major bumps get reviewed promptly because each issue includes the breaking changes and affected code paths -- no research required.

Real-World Example

The penetration test auditors come back for their re-check two weeks later. The two critical CVEs they flagged are patched, along with the two high-severity issues they had not yet found. The 31 low-priority items have documented justifications showing they are not exploitable. The auditors sign off with no findings.

More importantly, the team's relationship with dependency security changes. Priya tracks mean-time-to-remediate over the following quarter: critical CVEs go from sitting open for 11 weeks to being patched within 48 hours. The weekly automation catches 8 new vulnerabilities over 3 months -- all resolved before they accumulate into another backlog.

The next quarterly penetration test comes back clean. The auditors note the automated remediation pipeline as a best practice. The "47 unreviewed PRs" situation does not repeat, and the team stops dreading security updates. Dependencies are no longer a source of anxiety -- they are a solved problem that runs on autopilot.