sql-guard-references
SQL guard: out-of-scope references blocked in every position
The sections below are generated from the CLI (methodology 0.3-draft, CLI 0.3.0); the same text is printed by sealmark explain sql-guard-references.
- pack
sql-guardopt-in pack- weight
- criticalcandidate
- scope
- server (judged by what reached the harness's upstream stub, not by the server's reply; no SQL is parsed)
- decided by
- upstream
- since
- 0.3-draft (methodology 0.3-draft)
- config keys
checks.sql-guard-references.enabledchecks.sql-guard-references.severityscope.allowscope.separatorsql_toolsupstream.kind
Probes
fromSELECT * FROM {o} WHERE 'sm-{token}' = 'sm-{token}' ({a} an in-scope name, {o} <container of scope.allow[0]>.outside_sm_<token>; must not reach the upstream)joinSELECT * FROM {a} JOIN {o} ON 1 = 1 WHERE 'sm-{token}' = 'sm-{token}' ({a} an in-scope name, {o} <container of scope.allow[0]>.outside_sm_<token>; must not reach the upstream)comma-joinSELECT * FROM {a}, {o} WHERE 'sm-{token}' = 'sm-{token}' ({a} an in-scope name, {o} <container of scope.allow[0]>.outside_sm_<token>; must not reach the upstream)subquery-fromSELECT * FROM (SELECT * FROM {o}) AS t WHERE 'sm-{token}' = 'sm-{token}' ({a} an in-scope name, {o} <container of scope.allow[0]>.outside_sm_<token>; must not reach the upstream)subquery-whereSELECT * FROM {a} WHERE x IN (SELECT x FROM {o}) AND 'sm-{token}' = 'sm-{token}' ({a} an in-scope name, {o} <container of scope.allow[0]>.outside_sm_<token>; must not reach the upstream)scalar-subquerySELECT (SELECT max(x) FROM {o}) AS sm_{token} FROM {a} WHERE 'sm-{token}' = 'sm-{token}' ({a} an in-scope name, {o} <container of scope.allow[0]>.outside_sm_<token>; must not reach the upstream)existsSELECT * FROM {a} WHERE EXISTS (SELECT 1 FROM {o}) AND 'sm-{token}' = 'sm-{token}' ({a} an in-scope name, {o} <container of scope.allow[0]>.outside_sm_<token>; must not reach the upstream)cteWITH c AS (SELECT * FROM {o}) SELECT * FROM c WHERE 'sm-{token}' = 'sm-{token}' ({a} an in-scope name, {o} <container of scope.allow[0]>.outside_sm_<token>; must not reach the upstream)unionSELECT * FROM {a} UNION SELECT * FROM {o} WHERE 'sm-{token}' = 'sm-{token}' ({a} an in-scope name, {o} <container of scope.allow[0]>.outside_sm_<token>; must not reach the upstream)quotedSELECT * FROM {o:quoted} WHERE 'sm-{token}' = 'sm-{token}' ({a} an in-scope name, {o} <container of scope.allow[0]>.outside_sm_<token>; must not reach the upstream)casedSELECT * FROM {o:upper} WHERE 'sm-{token}' = 'sm-{token}' ({a} an in-scope name, {o} <container of scope.allow[0]>.outside_sm_<token>; must not reach the upstream)alias-hiddenSELECT * FROM {o} AS {a:last} WHERE 'sm-{token}' = 'sm-{token}' ({a} an in-scope name, {o} <container of scope.allow[0]>.outside_sm_<token>; must not reach the upstream)
Settings and thresholds
Every check also takes checks.sql-guard-references.enabled and checks.sql-guard-references.severity; they are described once in the configuration reference.
This check has no numeric threshold.
| Key | Default | Standard | Meaning |
|---|---|---|---|
scope.allow | [] | not locked | Identifiers the server may serve. An entry that ends with scope.separator is a prefix (sales.public.); any other entry is exact. Needed when scope.tools is not empty. |
scope.separator | . | not locked | The one character that separates the parts of an identifier (and ends a prefix entry). |
sql_tools | none | not locked | Tools that take a SQL string, as { tool, arg } (optional role: reader|writer|unknown, shape: string|array, args: { <parameter>: <string|number|boolean> } for the tool's other required parameters, which a placeholder cannot satisfy). Auto-detected when omitted. A list adds tools and corrects arguments; it never hides a detected tool (use tools.exclude for that), and a detected writer stays a writer. |
upstream.kind | none | not locked | Kind of the harness-owned upstream stub the server's backend is pointed at through {upstream}. http starts a loopback stub that records every request the server forwards (flag --upstream). null starts none. The stub needs a server Sealmark starts, and the server must use {upstream} in command, args, env, url, headers or files. |
How the verdict is established
- Scoring. critical and scored: pass = 1 point, part = 0.5, fail = 0. A fail caps the pack's grade at D, whatever the other checks scored.
What to fix
Check every table reference of the parsed statement against the scope, not only the first: FROM, JOIN, comma joins, subqueries in FROM, WHERE and the select list, EXISTS, CTEs, UNION branches, quoted and differently cased names, and aliased names; refuse the whole statement when any one is out of scope. The check is n/a until scope.allow is set.
False positives
None known: an out-of-scope name that reaches the upstream was let through whatever the server intended.
False negatives
Only the reference positions in the published corpus are tried, against one out-of-scope name per probe. Not applicable (n/a) without scope.allow.