SAST — Static Application Security Testing¶
Statement¶
ClaimGuard runs Snyk Code as the static analysis tool over its TypeScript/JavaScript and Python codebases. Every Snyk Code finding is either fixed in source or formally deferred in the deferral policy file with a per-finding justification that names the code-level invariant the analyzer missed.
Implementation¶
Tooling¶
- Engine: Snyk Code.
- Languages covered: Node.js / TypeScript (
server/,src/,functions/), Python (tools/). - Last full scan: 2026-04-22 (the engagement that produced the Snyk summary).
What Snyk Code flagged and how it was disposed¶
Snyk Code findings fall into two categories:
- Real findings — fixed in source. Examples on this codebase:
- SQL injection in claims/admin queries → parameterized queries
throughout (
P0-02-sql-injection.md). - DOM XSS in a React render path → React Router 6.30.x bump
(
P2-02-dom-xss.md). - Path traversal in upload + internal handlers →
safePathandsafe_path.pycontainment helpers, applied at every entry point (P1-02-path-traversal-http.md,P2-05-path-traversal-internal.md). -
DOM open redirect in the React Router shell (
P2-03-open-redirect.md). -
False positives — kept in source as documented invariants, with a the deferral policy file entry that names what the analyzer missed:
- UUID gates the analyzer treats as untrusted input even though the value passed a strict regex check.
- Whitelisted column names in dynamic SQL — the analyzer flags the dynamic concat; the actual code only accepts values from a hardcoded allowlist.
- Path containment helpers (
safePath,isInside) the analyzer can't follow through a function boundary. - Service-layer the outbound-HTTP wrapper wraps — an outbound
fetchreached through the keystone but flagged on the inner call site. - localStorage KEY-name reads the analyzer treats as PII reads when the code is reading the name of a key, not its value.
Every false-positive entry in the deferral policy file carries a reason: field that
names the specific guard the analyzer missed. None are blanket
suppressions.
Reachability and flow-confirmation¶
For severity-tier findings (P0/P1), each finding has an attached note in per-finding decision records that walks the actual call path — not just the analyzer's reported flow — and confirms the input source and sink. This keeps the team honest about whether a fix is at the right layer (e.g., fixing at the route guard vs. at the database driver).
Engineering invariants enforced via SAST¶
The findings exercise has produced a set of invariants documented in the internal security README that future SAST runs are expected to keep clean:
- All outbound HTTP routes through the outbound-HTTP wrapper module.
- All filesystem path joins go through
safePath(server/) orsafe_path.py(tools/). - All dynamic SQL goes through parameterized queries; column-name selection uses an allowlist.
When a Snyk Code finding contradicts one of these invariants, the fix is in source — not in the deferral policy file.
Status¶
implemented — verified 2026-04-26.
The 2026-04-22 Snyk Code findings were either fixed in source or formally deferred. The the deferral policy file is the authoritative record; all deferrals expire 2027-04-22 and are scheduled for annual review.
Roadmap¶
- CI integration — run
snyk code teston every PR with branch protection blocking new high-severity findings. - PR comment integration — surface SAST findings inline so reviewers see them without leaving the PR.
Known SAST tooling caveats¶
snyk code testdoes not machine-apply the deferral policy file ignores via the CLI for Snyk Code rules; entries underjavascript/*andpython/*rule keys are for the Snyk web UI / documentation. Locally, the CLI will still report deferred findings — engineers must cross-reference the deferral policy file.- Snyk's CLI walks
node_modules/.cacheand similar agent-side temp directories by default. Internal scan jobs filter.claude/worktrees/*from output to avoid double-counting findings from stale agent worktrees.