Case Studies
The first end-to-end run against a real application: one verified and fixed finding, one high-severity candidate refuted, and a stale build cache that nearly faked a fix.
The run record
The gamingops-store case study is the first end-to-end SecHelix run recorded against a real application rather than a synthetic fixture. It is published because the outcome is useful in both directions: one finding was verified and fixed, and one plausible high-severity candidate was refuted.
| Field | Value |
|---|---|
| Date | 2026-09-01 |
| Authorization | Repository owner auditing their own private repository |
| Execution mode | STATIC review plus LOCAL runtime reproduction |
| Agent host | Claude Code |
| Scanners enabled | None — code review plus local runtime observation |
| Tools | Next.js production build, vitest, Chromium via Playwright, curl |
| Target size | About 600 lines of TypeScript and TSX across 19 source files |
| External systems contacted | None; a local mock stood in for the upstream config API |
What the workflow produced
| Stage | Result |
|---|---|
| Attack surface | 1 external data source, 3 public routes, 0 authenticated actions |
| Applicable hypotheses | 41 of 546 |
| Candidates raised | 3 |
| Verified findings | 1 |
| Refuted candidates | 2 |
| Fixed | 1 verified plus 1 hardening |
| Regression tests added | 10 |
| Release decision | PASS after remediation |
Three candidates, one finding. That ratio is the workflow behaving as designed, and it is the reason the case study is more informative than a list of confirmed issues would have been.
The verified finding
SHX-F-GOS-HEADERS-001, Medium. No response security headers were declared, so any origin could frame the storefront. The Next.js configuration contained only an images block, and the production build emitted no Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Strict-Transport-Security, or Permissions-Policy.
All seven evidence links were established:
- Attacker control — the attacker owns the page that embeds the storefront.
- Reachability — every public route was served without a framing policy.
- Boundary failure — no frame-ancestors and no X-Frame-Options, so the permissive browser default applied.
- Safe reproduction — a local probe page on a separate origin embedded the storefront and the whole interface rendered. Nothing outside 127.0.0.1 was contacted.
- Impact — UI redress. An overlay can bait clicks onto the sign-in and purchase calls to action.
- Preconditions — a victim visits the attacker page while the storefront is reachable.
- Root cause — the application never declared a security header policy at all.
The honest severity is Medium, not High: the realistic outcome is phishing amplification and brand abuse rather than direct account takeover, because the application performs no authenticated state-changing actions. The fix was a catch-all headers rule with frame-ancestors none, X-Frame-Options: DENY, nosniff, referrer policy, Permissions-Policy, HSTS, and COOP, plus disabling the powered-by header.
Framing 'http://localhost:3009/' violates the following Content Security Policy
directive: "frame-ancestors 'none'". The request has been blocked.The refuted candidate
SHX-F-GOS-URLSCHEME-001. Remote store-configuration values flowed into href and src attributes with only a trim applied. This is exactly the shape a scanner or a confident reviewer reports as high-severity cross-site scripting.
Independent verification refuted it. A local mock configuration API served a javascript: URL, and the rendered document contained:
href="javascript:throw new Error('React has blocked a javascript: URL as a security precaution.')"React 19 neutralizes javascript: URLs before they reach the document, so no script execution was achievable through this path. Attacker control was independently not established either: the configuration source is the operator own workspace API, not an internet-reachable input. Recorded outcome: FALSE_POSITIVE, with the refutation reason retained.
A second candidate — a suspected PII leak in a buyer-name masking helper — was also rejected after tracing every code path returned a masked value.
A finding about the process
The first retest 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.
This is recorded because it is the kind of detail that silently converts a real fix into a false claim of remediation. It is also a direct instance of a SecHelix rule: a green typecheck is not proof that a built application is fixed.
Limitations
- One small application of about 600 lines, with no authentication and no server-side state.
- No scanners were enabled; this was code review plus local runtime observation.
- Coverage numbers describe hypotheses considered applicable to this architecture. They are not a claim about the framework accuracy.
- The severity assigned to the verified finding is a judgement, not a CVSS computation.
- This run measures nothing about SecHelix performance in general. It is one audit.
Artifacts — response headers before and after, framing reproduction screenshots, the refutation transcript, and the regression output — are referenced from the canonical report with a SHA-256 digest each. The canonical report is examples/report.example.json, it validates against report-v1, and the release gate returns PASS.