Fix Security Vulnerability Skill
Analyze Dependabot security alerts and propose fixes for the sentry-changelog Next.js app. Does NOT auto-commit - always presents analysis first and waits for user approval.
Input
- •Dependabot URL:
https://github.com/getsentry/sentry-changelog/security/dependabot/12 - •Or just the alert number:
12
Workflow
Step 1: Fetch Vulnerability Details
gh api repos/getsentry/sentry-changelog/dependabot/alerts/<alert-number>
Extract: package name, vulnerable/patched versions, CVE ID, severity, description.
Step 2: Analyze Dependency Tree
pnpm why <package-name>
Determine if it's a direct or transitive dependency, and whether it's production or dev.
Step 3: Determine Fix Strategy
Check for pinned dependencies
Some dependencies are intentionally pinned due to compatibility constraints. Check package.json comments (the "//" field) for pin reasons before bumping.
Known pins:
- •
google-auth-library- Pinned to v9.x to match@google-cloud/storage's bundled version (v10.x breaks Vercel OIDC auth)
For other dependencies
| Type | Action |
|---|---|
| Patch bump available | Preferred - lowest risk |
| Minor bump needed | Usually safe |
| Major bump needed | Analyze breaking changes first |
| Transitive dependency | Bump the parent package (see below) |
Step 3a: Transitive Dependencies
If the vulnerable package is pulled in by another package:
1. Identify and check the parent:
pnpm why <vulnerable-package> npm view <parent-package>@latest dependencies.<vulnerable-package>
2. Fix approach:
| Scenario | Action |
|---|---|
| Parent has newer version with fix | Bump the parent |
| Parent hasn't released fix | Wait, or open an issue upstream |
AVOID pnpm.overrides. Forcing a transitive dependency version can break the parent package silently. Only consider overrides if:
- •No upstream fix exists AND it's a production-critical vulnerability
- •The forced version is a patch/minor bump (not major)
- •You've manually verified compatibility
Step 4: Present Analysis
Present findings and wait for user approval before making changes:
## Security Vulnerability Analysis **Package:** <name> | **Severity:** <severity> | **CVE:** <id> **Vulnerable:** <range> | **Patched:** <version> ### Dependency Chain <pnpm why output> ### Recommendation <One of: Safe to bump / Intentionally pinned - do not bump / Bump parent package> ### Proposed Fix 1. Update package.json: "<package>": "<new-version>" 2. pnpm install 3. Verify with: pnpm why <package> Proceed?
Step 5: Apply Fix (After Approval)
# 1. Edit package.json # 2. Update lockfile pnpm install # 3. Verify pnpm why <package> # 4. Run tests pnpm test:run # 5. Show changes git diff
Do NOT commit - let the user review first.
Step 5 (Alternative): Dismiss Alert
For alerts that should not be fixed, offer to dismiss instead.
Always get user approval first. Present the dismissal option:
This alert should be dismissed rather than fixed because: - <reason: intentionally pinned / dev-only acceptable risk / etc.> Dismiss with reason: <suggested reason> Comment: "<suggested comment>" Proceed with dismissal?
After user approval, dismiss via GitHub API:
gh api --method PATCH repos/getsentry/sentry-changelog/dependabot/alerts/<number> \ -f state=dismissed \ -f dismissed_reason=<reason> \ -f dismissed_comment="<comment>"
Dismissal reasons:
| Reason | When to use |
|---|---|
tolerable_risk | Dev-only dependency, risk accepted |
no_bandwidth | Will fix later, not urgent |
inaccurate | False positive, not actually vulnerable |
not_used | Vulnerable code path is not used in our code |
Commands Reference
| Command | Purpose |
|---|---|
pnpm why <pkg> | Show dependency tree |
gh api repos/getsentry/sentry-changelog/dependabot/alerts/<n> | Fetch alert |
gh api --method PATCH .../dependabot/alerts/<n> -f state=dismissed -f dismissed_reason=<reason> | Dismiss alert |
npm view <pkg>@latest dependencies.<dep> | Check transitive dep version |
pnpm test:run | Run tests |
Examples
Direct dependency - safe to bump
Package: contentful Severity: moderate Type: Production dependency (direct) Recommendation: Safe to bump 10.15.0 → 10.16.0 - Patch version, low risk - No breaking changes expected
Pinned dependency - dismiss instead
Package: google-auth-library Severity: high Recommendation: DISMISS (do not bump to v10.x) This package is intentionally pinned to v9.x for compatibility with @google-cloud/storage's bundled ExternalAccountClient. Bumping to v10.x breaks Vercel OIDC authentication. Proposed dismissal: Reason: tolerable_risk Comment: "Pinned to v9.x for @google-cloud/storage compat - see package.json comments" Proceed with dismissal?
Transitive dependency - bump parent
Package: vulnerable-lib@1.9.0 (needs >=2.0.1) Chain: @sentry/nextjs → @sentry/node → vulnerable-lib Check: npm view @sentry/nextjs@latest dependencies Result: Uses patched version ✓ Recommendation: Bump @sentry/nextjs 10.32.1 → 10.33.0 This pulls in the patched vulnerable-lib automatically.
Transitive dependency - no fix available
Package: deep-lib@2.9.0 (needs >=3.0.0) Chain: next → some-pkg → deep-lib No upstream fix available yet. Options: 1. Wait for upstream fix (preferred) 2. Accept risk if dev-only 3. Consider pnpm.overrides as last resort for production-critical issues AVOID using overrides unless absolutely necessary.
Important Notes
- •Never auto-commit - Always wait for user review
- •Check pin reasons - Some deps are pinned for compatibility (see
"//"in package.json) - •Dev vs Prod matters - Dev-only vulnerabilities are lower priority
- •Bump parents, not transitive deps - If A depends on vulnerable B, bump A
- •Avoid
pnpm.overrides- They bypass the parent's dependency constraints and can cause subtle breakage - •Always verify - Run
pnpm why <pkg>after fixing to confirm the patched version is installed - •Run tests - Run
pnpm test:runafter fixing to make sure nothing broke