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 .snyk 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
.snykentry 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
safeFetchwraps — an outboundfetchreached 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 .snyk 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
docs/security/findings/ 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
docs/security/README.md that future SAST runs are expected to keep
clean:
- All outbound HTTP routes through
server/src/lib/safeFetch.js. - 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 .snyk.
Status¶
implemented — verified 2026-04-26.
The 2026-04-22 Snyk Code findings were either fixed in source or
formally deferred. The .snyk 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.snykignores 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.snyk.- 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.