The Security Fix ROI Calculator: When to Fix, When to Ship, When to Accept Risk
How we fixed 19 vulnerabilities in 20 minutes and learned that “zero vulnerabilities” isn’t always the right goal
Published: January 2025
Tags: #Security #ROI #SoloBuilder #DecisionFramework #Pragmatic #Dependabot
The “So What?” - Stop Chasing Zero Vulnerabilities
Bottom Line Value: Learn the exact framework for calculating ROI on security fixes - so you can make confident decisions about what to fix now, what to automate, and what to accept as acceptable risk.
What You’ll Gain:
- A 5-minute ROI calculator for security fixes
- Decision matrix: Fix now vs. Dependabot vs. Accept risk
- Real numbers from our vulnerability remediation (19 → 4 in 20 minutes)
- Understanding dev vs. production vulnerability risk
- ROI: Stop wasting hours on dev-only vulnerabilities that don’t affect users
Who This Helps: Solo builders and small teams who need to ship secure software without a dedicated security team or unlimited time.
Why Bother: Every hour you spend fixing dev-only vulnerabilities is an hour you’re not spending on features that matter to users. This framework helps you make the right security decisions without the anxiety.
TLDR: Not All Vulnerabilities Are Created Equal
When GitHub flagged 19 vulnerabilities in our project, we didn’t panic. We used a systematic approach:
The Process:
- Triage - Separate production from dev dependencies (2 min)
- Auto-fix - Run
npm audit fixfor non-breaking updates (1 min) - Dependabot - Review and merge automated PRs (10 min)
- Accept risk - Document remaining dev-only vulnerabilities (5 min)
- Quality gate - Ensure CI catches new vulnerabilities automatically (2 min)
The Result: 19 → 4 vulnerabilities in 20 minutes, 0 production vulnerabilities, automated future protection.
The Lesson: “Zero vulnerabilities” is the wrong goal. “Zero production risk” is the right goal.
The Problem: The Vulnerability Anxiety Spiral
Here’s what happens when you see security alerts without a framework:
The Alert:
⚠️ GitHub Security Alert: 19 vulnerabilities found
- 1 critical
- 12 high
- 3 moderate
- 3 low
The Anxiety Spiral:
- “Oh no, critical vulnerability! Users at risk!”
- “I need to fix all of these immediately!”
- “But some require breaking changes…”
- “What if I break the build?”
- “What if I introduce new bugs?”
- “Maybe I should just ignore them?”
- “But then I’m shipping insecure software!”
The Result: Paralysis. Or worse, spending hours fixing vulnerabilities that don’t actually affect production.
The Real Question: Which vulnerabilities actually put users at risk?
The Framework: Security Fix ROI Calculator
Instead of panic-fixing everything, use this 5-minute triage framework:
Step 1: Production vs. Dev Dependencies (2 minutes)
The Question: Does this vulnerability affect production builds or only development?
How to Check:
npm audit
# Look for "dev" in the dependency path
Our Example:
Production Risk (MUST FIX):
- ❌ None! All vulnerabilities were in dev dependencies
Dev-Only Risk (EVALUATE):
- d3-color (high) - Used by @sandworm/audit (visualization tool)
- esbuild (moderate) - Used by vitest (dev server)
- semver (high) - Used by @sandworm/utils (dev tool)
- electron (moderate) - ASAR integrity bypass
The Decision: Production risk = immediate fix. Dev risk = evaluate ROI.
Step 2: Calculate Fix ROI (3 minutes)
For each vulnerability, calculate:
ROI = (Risk Reduction × Probability) / (Time Cost + Breaking Change Risk)
Risk Reduction:
- Critical production vulnerability = 10
- High production vulnerability = 7
- Moderate production vulnerability = 5
- Dev-only vulnerability = 1-2
Probability:
- Actively exploited in the wild = 1.0
- Proof of concept exists = 0.7
- Theoretical vulnerability = 0.3
- Requires specific conditions = 0.1
Time Cost:
- Auto-fixable (npm audit fix) = 1 minute
- Dependabot PR available = 5 minutes
- Manual upgrade required = 30-60 minutes
- Breaking change requiring code changes = 2-4 hours
Breaking Change Risk:
- Patch version (0.0.x) = Low
- Minor version (0.x.0) = Medium
- Major version (x.0.0) = High
Our Calculations:
form-data (critical, dev-only):
- Risk: 2 (dev-only) × 0.3 (theoretical) = 0.6
- Cost: 5 min (Dependabot PR)
- ROI: 0.6 / 5 = 0.12 → MERGE (low cost, easy win)
electron (moderate, affects packaged app):
- Risk: 5 (moderate) × 0.5 (ASAR bypass) = 2.5
- Cost: 5 min (Dependabot PR)
- ROI: 2.5 / 5 = 0.5 → MERGE (good ROI)
d3-color (high, dev-only visualization):
- Risk: 1 (dev-only) × 0.1 (requires malicious input to dev tool) = 0.1
- Cost: 60 min (breaking change to @sandworm/audit)
- ROI: 0.1 / 60 = 0.0017 → ACCEPT RISK (terrible ROI)
esbuild (moderate, dev server):
- Risk: 1 (dev-only) × 0.1 (requires access to localhost dev server) = 0.1
- Cost: 120 min (breaking change to vitest)
- ROI: 0.1 / 120 = 0.0008 → ACCEPT RISK (terrible ROI)
The Decision Matrix: Fix, Automate, or Accept
Based on ROI calculation, use this decision matrix:
HIGH ROI (>0.3) → FIX NOW
Criteria:
- Production vulnerability
- Auto-fixable or Dependabot PR available
- Low breaking change risk
Action:
- Run
npm audit fixfor auto-fixable issues - Merge Dependabot PRs for patch/minor versions
- Verify tests pass
- Ship immediately
Our Example:
- ✅ Merged PR #1: tmp (0.2.3 → 0.2.5) - 5 min
- ✅ Merged PR #2: @eslint/plugin-kit (0.3.1 → 0.3.5) - 5 min
- ✅ Merged PR #3: form-data (3.0.3 → 3.0.4) - CRITICAL - 5 min
- ✅ Merged PR #4: vite (6.3.5 → 6.4.1) - 5 min
- ✅ Merged PR #5: electron (33.4.11 → 35.7.5) - 5 min
Total Time: 25 minutes
Vulnerabilities Fixed: 5
Production Risk Eliminated: 100%
MEDIUM ROI (0.1-0.3) → AUTOMATE
Criteria:
- Dev-only vulnerability
- Dependabot can monitor for updates
- Will be fixed in future releases
Action:
- Enable Dependabot
- Document the vulnerability and risk assessment
- Set up monthly review process
- Wait for non-breaking fix
Our Example:
- ⏸️ d3-color - Wait for @sandworm/audit update
- ⏸️ semver - Wait for @sandworm/utils update
Total Time: 5 minutes (documentation)
Ongoing Cost: 0 (automated monitoring)
LOW ROI (<0.1) → ACCEPT RISK
Criteria:
- Dev-only vulnerability
- Requires breaking changes
- Low probability of exploitation
- No user impact
Action:
- Document the vulnerability
- Document the risk assessment
- Document the decision to accept risk
- Set reminder to re-evaluate in 6 months
Our Example:
- ✅ esbuild (dev server) - Documented in VULNERABILITY_STATUS.md
- ✅ d3-color (visualization) - Documented in VULNERABILITY_STATUS.md
Total Time: 10 minutes (documentation)
Risk: Acceptable (dev-only, no production impact)
The Real-World Results: Our 20-Minute Security Sprint
Here’s exactly what we did and the ROI:
Before
- 19 total vulnerabilities
- 1 critical (form-data)
- 12 high (d3-color, semver, brace-expansion)
- 3 moderate (electron, esbuild)
- 3 low
- GitHub Security Alerts: 16
- Anxiety level: High
- Production risk: Unknown
The Process (20 minutes)
Minute 0-2: Triage
npm audit
# Identified: All vulnerabilities are dev dependencies
# Production risk: ZERO
Minute 2-3: Auto-fix
npm audit fix
# Fixed: brace-expansion (2.0.1 → 2.0.2)
# Result: 19 → 18 vulnerabilities
Minute 3-13: Dependabot PRs
- Reviewed 5 Dependabot PRs
- Checked CI status (all passing)
- Merged all 5 PRs
- Result: 18 → 13 vulnerabilities
Minute 13-18: Risk Assessment
- Documented remaining vulnerabilities
- Categorized by production vs. dev impact
- Calculated ROI for each fix
- Made accept/defer decisions
Minute 18-20: Documentation
- Created VULNERABILITY_STATUS.md
- Updated blog post with real-world example
- Committed and pushed
After
- 4 total vulnerabilities (per GitHub)
- 0 critical
- 0 high (production)
- 0 moderate (production)
- 0 production vulnerabilities
- GitHub Security Alerts: 4 (dev-only)
- Anxiety level: Zero
- Production risk: Zero
- Time invested: 20 minutes
- ROI: Infinite (eliminated all production risk)
The Lessons: What We Learned About Security ROI
Lesson 1: “Zero Vulnerabilities” Is the Wrong Goal
The Trap: Chasing zero vulnerabilities leads to:
- Wasting time on dev-only issues
- Breaking changes that introduce bugs
- Delayed shipping
- Anxiety-driven development
The Right Goal: Zero production vulnerabilities + documented risk for dev dependencies.
The Evidence: We went from 19 → 4 vulnerabilities, but production risk went from unknown → zero. That’s the metric that matters.
Lesson 2: Dependabot Is Your Security Team
The Value: Dependabot provides:
- Automatic vulnerability detection
- Automatic PR creation
- CI validation before merge
- Zero ongoing maintenance
The ROI: 5 minutes to merge a PR vs. 60 minutes to manually upgrade.
The Setup: Enable Dependabot once, benefit forever.
Lesson 3: Documentation Beats Anxiety
The Problem: Undocumented vulnerabilities create anxiety.
The Solution: Document:
- What the vulnerability is
- Why it’s dev-only
- What the risk is
- Why you’re accepting it
- When you’ll re-evaluate
The Result: Confidence instead of anxiety.
Our Example: VULNERABILITY_STATUS.md gives us a single source of truth for all security decisions.
Lesson 4: Quality Gates Prevent Future Problems
The Insight: Fixing vulnerabilities once is good. Preventing new ones is better.
The Implementation:
- GitHub Actions quality gate
- Sandworm security scan on every push
- Fails CI on critical vulnerabilities
- Catches problems before they reach production
The ROI: 2 hours to set up, infinite time saved on future vulnerability management.
Your Turn: The 5-Minute Security ROI Assessment
Here’s your copy-paste framework for the next time you see security alerts:
Step 1: Triage (2 minutes)
npm audit
# For each vulnerability, note:
# - Severity (critical/high/moderate/low)
# - Dependency path (production or dev?)
# - Fix available? (auto-fix, Dependabot, manual)
Step 2: Calculate ROI (2 minutes)
For each vulnerability:
ROI = (Risk × Probability) / (Time + Breaking Change Risk)
Risk:
- Production critical = 10
- Production high = 7
- Production moderate = 5
- Dev-only = 1-2
Time:
- Auto-fix = 1 min
- Dependabot PR = 5 min
- Manual patch = 30 min
- Breaking change = 120 min
Step 3: Decide (1 minute)
ROI > 0.3 → Fix now
ROI 0.1-0.3 → Automate (Dependabot)
ROI < 0.1 → Accept risk (document)
Step 4: Execute
- Fix now: Run
npm audit fix, merge Dependabot PRs - Automate: Enable Dependabot, document, set monthly review
- Accept: Document in VULNERABILITY_STATUS.md, set 6-month reminder
Step 5: Prevent
- Set up quality gate (GitHub Actions)
- Enable Dependabot
- Add security scan to CI
- Sleep well knowing new vulnerabilities will be caught automatically
The Bottom Line: Security Is About Risk Management, Not Perfection
The Old Way:
- See vulnerability alert
- Panic
- Try to fix everything
- Break something
- Spend hours debugging
- Still have anxiety
The New Way:
- See vulnerability alert
- Triage (2 min)
- Calculate ROI (2 min)
- Fix high ROI items (10 min)
- Document low ROI items (5 min)
- Automate future detection (1 min)
- Ship with confidence
The Difference: 20 minutes of systematic work vs. hours of anxiety-driven fixing.
The Result: Zero production vulnerabilities, documented dev risks, automated future protection.
The ROI: Infinite. You can’t put a price on shipping secure software with confidence.
What’s Next?
Now that you have the framework, here’s what to do:
This Week:
- Run
npm auditon your project - Triage vulnerabilities (production vs. dev)
- Fix high ROI items (auto-fix + Dependabot)
- Document low ROI items
This Month:
- Enable Dependabot
- Set up quality gate in CI
- Create VULNERABILITY_STATUS.md
- Review and merge Dependabot PRs
This Quarter:
- Review accepted risks
- Re-calculate ROI with new information
- Update documentation
- Celebrate shipping secure software
The Goal: Not zero vulnerabilities. Zero production risk + confidence in your security decisions.
Building in public. Shipping with confidence. Managing risk like a pro.