技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
detecting-sql-injection-patterns【数据与研究】Scan a source tree for SQL-injection vulnerable patterns: string concatenation into queries, f-string interpolation in SQL, string-format substitution into raw queries, deprecated cursor methods (cursor.execute with % formatting), Knex / Sequelize raw() with template interpolation, sequelize.query with replacements. Use when: pre-commit code review, …
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
name: detecting-sql-injection-patterns description: | Scan a source tree for SQL-injection vulnerable patterns: string concatenation into queries, f-string interpolation in SQL, string-format substitution into raw queries, deprecated cursor methods (cursor.execute with % formatting), Knex / Sequelize raw() with template interpolation, sequelize.query with replacements. Use when: pre-commit code review, post-feature SQL-touching release, inheriting a legacy codebase that predates ORMs, or post-bug-report investigation. Threshold: any source line where SQL keywords (SELECT / INSERT / UPDATE / DELETE / FROM / WHERE) appear in a string that's being built via concatenation, f-string, %-format, or .format() with variable input. Trigger with: "scan for sqli", "sql injection patterns", "check raw queries", "audit cursor.execute". allowed-tools:
SQL injection (CWE-89, OWASP A03:2021) remains one of the highest- impact and most-easily-introduced vulnerability classes. The fix is near-universal: use parameterized queries. The cause when introduced: an engineer concatenates user input into a SQL string because the ORM's parameterization mechanism wasn't obvious, or because they "just need to add a quick condition."
The scanner reads source files and grades each apparent SQL-string construction against the threshold table.
| Finding | Severity | Threshold | Affected control |
|---|---|---|---|
| f-string with SQL keywords + user input | CRITICAL | f"SELECT * FROM users WHERE id = {user_id}" | CWE-89 |
| String concat into SQL keyword string | CRITICAL | "SELECT ... " + var + " ..." | CWE-89 |
| %-format SQL string | HIGH | "SELECT * FROM %s" % table_name | CWE-89 |
.format() into SQL string | HIGH | "SELECT {} FROM users".format(col) | CWE-89 |
cursor.execute(f"...") | CRITICAL | f-string passed directly to cursor.execute | CWE-89 |
sequelize.query with template literal | HIGH | sequelize.query(\SELECT * FROM ${table}`)` | CWE-89 |
| Knex / sequelize raw() with interpolation | HIGH | knex.raw('SELECT * FROM ' + table) | CWE-89 |
Django .extra() with raw SQL | MEDIUM | Model.objects.extra(where=['col = ' + val]) | CWE-89 |
cursor.executemany with string-built query | CRITICAL | Same risk as execute | CWE-89 |
JDBC Statement.execute with concat | HIGH | Java pattern: not PreparedStatement | CWE-89 |
Rails where() with string interpolation | HIGH | User.where("name = '#{name}'") | CWE-89 |
Go db.Query with fmt.Sprintf | HIGH | db.Query(fmt.Sprintf("...", arg)) | CWE-89 |
python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-sql-injection-patterns/scripts/scan_sqli.py /path/to/repo
Options:
Usage: scan_sqli.py PATH [OPTIONS]
Options:
--output FILE Write findings to FILE
--format FMT json | jsonl | markdown (default: markdown)
--min-severity SEV (default: info)
--include-tests Include test directories (default: excluded)
--languages LIST Comma-separated: python,javascript,typescript,java,
ruby,go,php,csharp (default: all)
CRITICAL = direct user-input → query string construction. Fix the specific query AND audit nearby code for the same pattern.
HIGH = pattern suggests interpolation but might be a fixed identifier (table/column name). Verify by reading the code.
MEDIUM = framework-specific pattern that's safe ONLY with strict
input validation (Django .extra(), Rails string where()).
For each finding, the fix is the same shape per language: use the
language/library's parameterized-query API. See
references/PLAYBOOK.md for per-language snippets.
Consider running scanning-for-hardcoded-secrets (#10) on the same
target — same audit, different class of finding.
python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-sql-injection-patterns/scripts/scan_sqli.py \
--min-severity high $(git diff --name-only main...HEAD | tr '\n' ' ')
Scans only files changed in the current branch — fast feedback for PR review.
python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-sql-injection-patterns/scripts/scan_sqli.py \
/path/to/legacy-app --format markdown > sqli-audit.md
Expect dozens to hundreds of findings on a pre-ORM Java/PHP codebase. Prioritize by reachability: the queries reached from public endpoints first.
JSON / JSONL / Markdown. Exit codes: 0 clean, 1 high/critical, 2 error.
f"SELECT * FROM {tablename}" where tablename is hardcoded) →
verify manually. The scanner can't reason about variable
provenance without a full AST + control-flow pass.references/THEORY.md — Per-language interpolation patterns,
ORM-specific safe vs unsafe APIs, why prepared statements workreferences/PLAYBOOK.md — Per-language parameterization snippets
(Python sqlite3 + psycopg + SQLAlchemy, Node mysql2 + pg + knex