CI static analysis: typescript-eslint strict + Semgrep (#15) #41
No reviewers
Labels
No labels
area:auth
area:ci
area:db
area:infra
area:native
area:pwa
area:service
epic
feature
foundation
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
james/carol!41
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "15-static-analysis"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #15.
Summary
strictruleset on top ofnext/typescript, layered beforeprettier. Stays onstrict(notstrictTypeChecked) so lint doesn't re-run the type-checker — that's the dedicatedtypecheckjob's job.static-analysisForgejo Actions job that runs Semgrep against curated registry packs (p/javascript,p/typescript,p/nodejsscan,p/owasp-top-ten) plus a local.semgrep/pack of dangerous-API bans.eval,new Function, string-formsetTimeout/setInterval,sql.rawwith interpolated/concatenated strings, andchild_process.exec*with interpolation/concatenation. These are unconditional — there is no legitimate use of any of them in this codebase.tests/**to allow non-null assertions — in tests,value!after a known-good setup step is clearer thanif (!value) throwand a bad assertion fails the test with a useful error.Why a local Semgrep pack on top of the registry packs
While building this I confirmed empirically that Semgrep's curated
detect-eval-with-expressionand friends are taint rules — they only fire when the sink's input flows from a recognised browser source (location.href,URLSearchParams). A bareeval(req.body.code)in a Next.js route handler does not match. The registry packs are excellent at flow-shaped OWASP patterns but are not a dangerous-API ban tool, so the ticket's acceptance criteria (planteval, get a finding) needed the local pack. Full rationale in ADR-0005.Acceptance criteria
eval, raw-string SQL concatenation) trips the check in a throwaway branch. Verified locally with a scratch file containingeval(userInput),sql.raw("..." + userId),execSync("ls " + input), andnew Function(src)— all four trip the local Semgrep pack. Full-repo scan over current code is clean (0 findings).Test plan
eval(userInput)in a real source file and confirm the Static analysis job fails with a clear message.🤖 Generated with Claude Code
8de36338638c95cf40ec