Repository navigation
Commit 8ea1e4e
authored
fix(sql-sanitizer): fix UPDATE prose false block and missed inline li… (#191)
* fix(sql-sanitizer): fix UPDATE prose false block and missed inline literals
- UPDATE_RE now requires SET after the table name so that prose text
containing the word UPDATE (e.g. "Append UPDATE query to file") is
not matched as a DML statement and does not trigger the WHERE-less
UPDATE policy.
- require_parameterization now also detects inline literal values
(numeric and string) in addition to interpolation markers. SQL using
bind parameters (?, $1, :name) passes; SQL with hard-coded literals
is flagged with a new message.
- Add BIND_PARAM_DIGIT_RE to erase $N / :N / @n digit sequences before
literal detection so positional bind params are not false-positived.
- Regression tests added for: valid UPDATE with WHERE, prose UPDATE word,
mixed SQL+prose payload, INSERT/UPDATE with inline literals, and
INSERT/UPDATE with bind parameters.
- Version bumped 0.1.3 -> 0.1.4.
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
* fix(sql-sanitizer): update interpolation_marker test to use bind param
The existing test used a quoted LIKE literal '%s%' which the new inline
literal detection correctly flags as non-parameterized. Rewrite the
predicate to use a bind param so the test stays valid under both the
interpolation and inline-literal checks.
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
* fix(sql-sanitizer): fix schema-qualified UPDATE bypass and non-SQL field over-flagging
Blocker 1 — UPDATE_RE schema-qualified table bypass:
The table-name token was \w+ which does not match dots, so
'UPDATE schema.table SET …' failed to match and WHERE-less
updates on schema-qualified tables silently bypassed the guard.
Change the bare-identifier alternative to (?:\w+\.)*\w+ so that
dotted names (schema.table, db.schema.table) match as a single
unit before \s+SET\b.
Add regression tests:
schema_qualified_update_without_where_is_blocked
schema_qualified_update_with_where_is_not_blocked
three_part_name_update_without_where_is_blocked
Blocker 2 — has_inline_literals over-flags non-SQL fields:
With fields=null the scanner visits every string in the payload.
has_inline_literals fired on any field containing a digit (HTTP
status codes, tool-call IDs, version strings, log messages),
causing false blocks unrelated to the original parameterization
intent. Add a SQL_KEYWORD_RE gate: strings that contain no
DML/DQL keyword (SELECT, INSERT, UPDATE, DELETE, MERGE, REPLACE,
WITH) are skipped entirely.
Add regression tests:
non_sql_field_with_number_is_not_flagged
tool_call_id_field_is_not_flagged
version_string_is_not_flagged
error_code_message_is_not_flagged
select_one_health_check_is_flagged_as_inline_literal
Major — restore interpolation_marker_in_string_literal test:
The PR had rewritten the test body to use a bind param with no
quoted literal, making it test nothing about literal masking.
Replace with two focused tests:
percent_s_inside_string_literal_is_not_flagged_as_interpolation
— exercises mask_string_literals hiding %s inside a quote,
require_parameterization=false so only the interpolation
path is active.
parameterized_like_with_bind_param_is_not_flagged
— require_parameterization=true + LIKE ? passes cleanly.
Major — update config.rs require_parameterization doc comment:
The field doc described only the interpolation-marker path.
Expand it to cover both detection paths, the SQL-context gate,
and the fields=null caveat.
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
* style(sql-sanitizer): collapse three_part_name test call to single line for rustfmt
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
* style(sql-sanitizer): trim verbose comments to 1-2 lines
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
* fix(sql-sanitizer): cover UPDATE aliases/ONLY/quoted-schema, SQLite ?N params, hex/exp literals, DQ identifiers, drop WITH from SQL gate
P1 — UPDATE_RE now handles:
- ONLY keyword: UPDATE ONLY t SET
- AS alias / implicit alias: UPDATE t AS e SET, UPDATE t e SET
- Quoted schema.table: UPDATE "hr"."employees" SET
P2 — BIND_PARAM_DIGIT_RE: add ? so SQLite ?1/?2 params are erased.
P2 — SQL_KEYWORD_RE: remove WITH; it fires on common English prose
like "Request failed with status 503".
P2 — INLINE_LITERAL_RE: extend pattern to cover hex (0xFF) and
exponent (1e3, 1.5E-2) numeric literals.
P2 — has_inline_literals: strip ANSI double-quoted identifiers
(DQ_IDENT_RE) before literal matching so SELECT "2024" FROM t
WHERE id = $1 is not incorrectly blocked.
Regression tests added for all five cases.
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
* style(sql-sanitizer): collapse multi-line find_issues calls for rustfmt
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
* style(sql-sanitizer): expand two test call sites to match rustfmt
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
* fix(sql-sanitizer): add word boundary to hex literal pattern to prevent mid-identifier match
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
* fix(sql-sanitizer): accept quoted UPDATE aliases; require paired SQL keywords for literal gate
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
* fix(sql-sanitizer): fix test message mismatch and SELECT 1 gate expectation
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
* fix(sql-sanitizer): enable dot-all in SQL_CONTEXT_RE so multiline SQL is gated correctly
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
---------
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>1 parent c105ecd commit 8ea1e4e
6 files changed
Lines changed: 573 additions & 21 deletions
File tree
- plugins/rust/python-package/sql_sanitizer
- cpex_sql_sanitizer
- src
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | | - | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
43 | 45 | | |
44 | 46 | | |
45 | 47 | | |
| |||
0 commit comments