AI-powered security analysis of code changes — traces data flow, detects injection, auth bypass, secrets exposure, and unsafe deserialization across files. Use when reviewing pending changes, before release-branch, during verify-work Phase 5, during build-epic Step 0 threat modeling, or when the user says "security review" or "scan for vulns".
4description: "AI-powered security analysis of code changes — traces data flow, detects injection, auth bypass, secrets exposure, and unsafe deserialization across files. Use when reviewing pending changes, before release-branch, during verify-work Phase 5, during build-epic Step 0 threat modeling, or when the user says \"security review\" or \"scan for vulns\"."
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.
73| Developer-authored query with bound parameters only | No dynamic fragments from user input | **Safe** |
74| String concatenation / template with user-controlled values | Yes | **Unsafe** — report as SQLi |
75| ORM query builder with user input in WHERE/JOIN | Yes | **Unsafe** unless parameterized |
76| Stored procedure call with bound args | Args from trusted constants only | **Safe** |
77| Stored procedure with dynamic SQL inside | User input reaches EXEC | **Unsafe** |
78
79**Provenance test:** If the agent cannot prove the query string was authored entirely by the developer (no attacker-reachable interpolation), treat as vulnerable. Hardcoded SQL in migrations, seeds, and admin scripts is safe; anything reachable from HTTP/CLI/user input is not.
80
81## BCP Plus Integration
82
83This skill maps to **BCP Plus dimension 12 (Security & Compliance)**. When BCP Plus sizing is active, the threat model categories above correspond to sub-elements within dimension 12. The NFR Gate rule applies: standard-expectation items (e.g., "use HTTPS", "hash passwords") score 0 with a one-line rationale; only above-standard security requirements contribute to the dimension 12 count. See `docs/references/bcp-plus.md` for the full 13-dimension framework and NFR Gate pattern.
226| 10 | **Memory safety** in Rust or other memory-safe languages | Impossible by language guarantees |
227| 11 | **Hardcoded SQL with proven authorship** — migrations, seeds, static admin queries with no user interpolation | Developer-authored SQL is safe per SQL-safety doctrine (e45s41) |
228| 12 | **Unit test files only** | Not production risk |
229| 13 | **Log spoofing** | Outputting unsanitized input to logs is not a vuln |
230| 14 | **SSRF that only controls path** | Only host/protocol control is exploitable |
231| 15 | **User-controlled content in AI system prompts** | Not a security vulnerability |
232| 16 | **Regex injection** | Injecting untrusted content into regex is not a vuln |
233| 17 | **Regex DOS** | Excluded alongside general DOS |
234| 18 | **Documentation files** (.md, .txt) | Insecure docs are not code vulnerabilities |
235| 19 | **Lack of audit logs** | Not a vulnerability |
236
237## Precedent Rules
238
239These guide borderline cases based on prior human review decisions:
240
241| # | Precedent | Reasoning |
242|---|-----------|-----------|
243| 1 | **Logging high-value secrets in plaintext IS a vuln.** Logging URLs is safe. | Secrets in logs = credential exposure; URLs are not secrets |
244| 2 | **UUIDs are unguessable** — no validation needed | Cryptographic property of UUID v4/v7 |
245| 3 | **Environment variables and CLI flags are trusted values** | Attackers cannot modify these in secure environments |
246| 4 | **Resource management issues** (memory leaks, fd leaks) are NOT valid | Operational, not security |
247| 5 | **Tabnabbing, XS-Leaks, prototype pollution, open redirects** — do NOT report unless extremely high confidence | Subtle, low-impact, high false-positive rate |
289| **Safe** | Parameterized queries / ORM: `cursor.execute("SELECT * FROM users WHERE id = %s", (uid,))` |
290| **Look for** | f-strings, `+` concatenation, `format()` in query builders; raw SQL in ORM `.raw()` / `.execute()` |
291| **False-positive guard** | Not a FP if the input is user-controlled (HTTP param, file, env var, CLI arg). Env vars are trusted (see exclusion rules). |
367| **Look for** | `API_KEY=`, `password=`, `secret=`, `token=` in code; AWS keys, GitHub tokens, Stripe keys, JWTs in source |
368| **False-positive guard** | Secrets stored on disk but otherwise secured ARE excluded. Logging high-value secrets IS a vuln. Logging URLs is safe. |
369
370## Template Injection (SSTI)
371
372| Aspect | Detail |
373|--------|--------|
374| **Vulnerable** | User input in template rendering: `Template(user_input).render()`, `render_template_string(user_input)` |
375| **Safe** | Static templates; input passed as context variable, not template string |
376| **Look for** | `render_template_string`, `Template()()` with user string; `eval` in template context; `${user_input}` in JS template literals on server |
377
378## NoSQL Injection
379
380| Aspect | Detail |
381|--------|--------|
382| **Vulnerable** | User input in MongoDB queries: `db.users.find({username: user_input})` where input is `{"$gt": ""}` |
383| **Safe** | Schema validation; type checking on query params; ORM sanitization |
384| **Look for** | MongoDB `$where`, `$gt`, `$regex` from user input; raw mongo queries without type coercion |