Patch Verification
Confirm the patch actually fixes the vuln, doesn't break anything, and reaches production — the three checks before "done."
Why
A patch that passes CI but doesn't fix the vuln is worse than no patch — you've declared the vuln fixed, lowered its priority, and moved on, while the exploit still works. Verification is the three-part check that prevents this: (1) the regression test reproduces the vuln before the fix and passes after (proving the fix works), (2) the full test suite + e2e pass (proving the fix doesn't break anything), (3) the deployed version in prod matches the patched version (proving the fix reached production). Skipping any of these is how vulns get "fixed" and then re-exploited months later. Verification is cheap (minutes) and prevents the expensive failure (a re-exploit + a second incident + lost trust).
When
Before declaring any security patch "done." All three checks must pass before the advisory is published.
How
1. Fix-works check: run the regression test on the UNPATCHED code (should fail), then on the patched code (should pass) 2. Nothing-broke check: run the full unit + integration + e2e suite on the patched code; all must pass 3. Reached-prod check: after deploy, query the running version (GET /api/version) and confirm it matches the patched release 4. For dependency patches: verify the lockfile has the new version (npm ls <dep>) AND that the new version is actually loaded (not deduped away) 5. For config-based fixes: verify the config is deployed (curl the endpoint and confirm the behavior changed) 6. Record the verification in the advisory: "Verified: regression test passes, full suite green, prod version = v1.2.3" 7. Set a 30-day follow-up: re-check that the fix is still in prod (a rollback could have reverted it)
Example
# 1. Fix-works check (regression test before + after)
git checkout v1.2.2 # unpatched
npm test -- --grep "CVE-2024-9999" # FAILS (reproduces the vuln) ✓
git checkout hotfix/cve-2024-9999
npm test -- --grep "CVE-2024-9999" # PASSES (fix works) ✓
# 2. Nothing-broke check (full suite)
npm test && npm run e2e # all green ✓
# 3. Reached-prod check (after deploy)
curl https://api.ez4code.com/api/version
# { "version": "1.2.3", "commit": "abc1234" }
git rev-parse v1.2.3 # abc1234 # matches ✓
# 4. Dependency patch verification
npm ls lodash # -> 4.17.21 (patched) ✓
# confirm it's actually loaded (not deduped to an old copy):
node -e "console.log(require('lodash/package.json').version)" # 4.17.21 ✓
# Record in the advisory
# "Verified: regression test passes on v1.2.3, full suite green,
# prod /api/version returns 1.2.3, [email protected] confirmed loaded."
# 30-day follow-up (scheduled check)
# curl /api/version — still 1.2.3? (a rollback would revert the fix)Common Problems
- ⚠Publishing the advisory without verifying the fix reached prod — the patch is in the release but a deploy failed, and the vuln is still exploitable.
- ⚠A dependency patch where the lockfile has the new version but an old copy is deduped into the bundle — the fix is in node_modules but not in what runs.
- ⚠No follow-up check — a rollback 2 weeks later silently reverts the fix, and the vuln is re-exploited.
Best Practices
- ✓Run the regression test on both unpatched (must fail) and patched (must pass) code — this proves the fix works, not just that the test passes.
- ✓Verify the deployed prod version matches the patched release via /api/version — a patch that didn't deploy is a patch that didn't fix.
- ✓Set a 30-day follow-up to re-confirm the fix is still in prod — rollbacks happen, and a reverted fix is a re-exploit waiting.