Skip to content
SecHelixv3 alpha
GitHub
DocsContributeSupportWorkbenchGitHub
Core Concepts

Regression Proof

A fix is finished when a test fails against the vulnerable control and passes after the repair, at the layer where the invariant actually lives.

The sequence

For each verified important finding, remediation is complete only after all five steps.

  1. Fail firstProve the test fails against the vulnerable control where that is practical.
  2. Apply the fixRepair the canonical invariant.
  3. Prove it passesThe same test now passes.
  4. Neighbouring testsRun the focused tests around the changed boundary.
  5. Central gatesRun the security and release gates once the change is integrated.

Choosing the layer

Add regression proof at the level that catches the real failure. The correct layer is wherever the invariant actually lives, which is frequently not the layer the symptom appeared in.

Unit
A pure function invariant, such as a URL scheme allowlist or an amount normalizer.
Database
A constraint, a row policy, or a migration ordering property.
Integration
A two-subject authorization comparison across the real data-access boundary.
Browser
Client and server bundle boundaries, cookies, origins, redirects, CSP and DOM behaviour.
Release or build
Header policy, production build output, and configuration that only exists after a build.

A typecheck is not a browser bundle test. A source grep is not an authorization test. A mock is not proof of a database constraint if the vulnerability depends on that constraint.

Weak proofs

  • Source-text assertions are weak when the behaviour can be tested. Assert the behaviour instead.
  • If a refactor moves code, revalidate the property before updating a source assertion. Otherwise the assertion is tracking the file, not the invariant.
  • A passing suite on the vulnerable revision means the suite never covered the defect.
  • Tests that only exercise the fixed path leave the alternate endpoint, the bulk route, and the background job untested.

The stale-build trap

The published case study records a retest that appeared to fail: headers were still missing and the hostile URL still appeared in the DOM. The cause was a stale prerender cache plus a still-running server bound to the old port. Only a clean rebuild proved the fix.

The retest after a clean rebuild
Framing 'http://localhost:3009/' violates the following Content Security Policy
directive: "frame-ancestors 'none'". The request has been blocked.

That detail is documented because it silently converts a real fix into a false claim of remediation — and in the other direction, it can make a working fix look broken. Retest against a clean build, on the port you actually rebuilt.

Regression-proof rate

For verified findings that receive a fix, the regression-proof rate is the fraction with a test that fails before the fix and passes after it, plus a successful retest of the original claim. It is one of the six evaluation metrics and one of the recommended operational metrics for a rollout.