@askdb/core 1.0.0-beta.41 → 1.0.0-beta.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -1
- package/dist/ask.d.ts +39 -0
- package/dist/ask.d.ts.map +1 -1
- package/dist/ask.js +175 -10
- package/dist/ask.js.map +1 -1
- package/dist/errors.d.ts +49 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/logging/log-events.d.ts +13 -0
- package/dist/logging/log-events.d.ts.map +1 -1
- package/dist/logging/log-events.js +13 -0
- package/dist/logging/log-events.js.map +1 -1
- package/dist/sql/bind.d.ts +100 -0
- package/dist/sql/bind.d.ts.map +1 -0
- package/dist/sql/bind.js +560 -0
- package/dist/sql/bind.js.map +1 -0
- package/dist/sql/dialect-spec.d.ts +4 -0
- package/dist/sql/dialect-spec.d.ts.map +1 -1
- package/dist/sql/dialect-spec.js +8 -0
- package/dist/sql/dialect-spec.js.map +1 -1
- package/dist/sql/extract-sql.d.ts +8 -1
- package/dist/sql/extract-sql.d.ts.map +1 -1
- package/dist/sql/extract-sql.js +27 -4
- package/dist/sql/extract-sql.js.map +1 -1
- package/dist/sql/generate.d.ts +10 -0
- package/dist/sql/generate.d.ts.map +1 -1
- package/dist/sql/generate.js +72 -4
- package/dist/sql/generate.js.map +1 -1
- package/dist/sql/index.d.ts +4 -2
- package/dist/sql/index.d.ts.map +1 -1
- package/dist/sql/index.js +4 -2
- package/dist/sql/index.js.map +1 -1
- package/dist/sql/parameter-manifest.d.ts +34 -0
- package/dist/sql/parameter-manifest.d.ts.map +1 -0
- package/dist/sql/parameter-manifest.js +150 -0
- package/dist/sql/parameter-manifest.js.map +1 -0
- package/dist/sql/prompt.d.ts +7 -1
- package/dist/sql/prompt.d.ts.map +1 -1
- package/dist/sql/prompt.js +24 -1
- package/dist/sql/prompt.js.map +1 -1
- package/dist/sql/sensitive-guardrail.d.ts +47 -0
- package/dist/sql/sensitive-guardrail.d.ts.map +1 -0
- package/dist/sql/sensitive-guardrail.js +589 -0
- package/dist/sql/sensitive-guardrail.js.map +1 -0
- package/dist/sql/tenant-placeholders.d.ts +3 -2
- package/dist/sql/tenant-placeholders.d.ts.map +1 -1
- package/dist/sql/tenant-placeholders.js +14 -11
- package/dist/sql/tenant-placeholders.js.map +1 -1
- package/dist/sql/validate.d.ts.map +1 -1
- package/dist/sql/validate.js +1 -47
- package/dist/sql/validate.js.map +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,589 @@
|
|
|
1
|
+
import { SensitiveReferenceError, } from "../errors.js";
|
|
2
|
+
/**
|
|
3
|
+
* Check whether a SQL statement references tables/columns marked `sensitive`
|
|
4
|
+
* in the schema artifact.
|
|
5
|
+
*
|
|
6
|
+
* `sensitive: true` is otherwise a **prompt-level** marker: `formatSchemaForNlToSql`
|
|
7
|
+
* either tags identifiers `(sensitive)` or withholds them entirely. Both act on what
|
|
8
|
+
* the model *sees*. This function is the **enforcement** path — it inspects SQL that
|
|
9
|
+
* is about to execute, so hosts that cache, store, or replay statements should call it
|
|
10
|
+
* on every execution path, not only at generation time.
|
|
11
|
+
*
|
|
12
|
+
* Unlike a bare substring scan, an unqualified column name only counts when the owning
|
|
13
|
+
* table is actually in the statement's scope: `FROM`/`JOIN` targets and their aliases
|
|
14
|
+
* are resolved first. When scope cannot be resolved (no resolvable table source, or a
|
|
15
|
+
* qualifier that binds to nothing known), the check fails conservatively — it widens
|
|
16
|
+
* matching and reports why in {@link SensitiveGuardrailResult.unresolvedScope} — rather
|
|
17
|
+
* than passing silently.
|
|
18
|
+
*
|
|
19
|
+
* Heuristic, not a SQL parser. It is a review/enforcement aid, not a substitute for
|
|
20
|
+
* database-side column privileges.
|
|
21
|
+
*/
|
|
22
|
+
export function validateSensitiveReferences(sql, schema, options) {
|
|
23
|
+
const mode = options?.mode ?? "warn";
|
|
24
|
+
const index = indexSchema(schema);
|
|
25
|
+
const result = index.hasSensitive
|
|
26
|
+
? scan(sql, index)
|
|
27
|
+
: { passed: true, references: [] };
|
|
28
|
+
if (mode === "strict" && !result.passed) {
|
|
29
|
+
throw new SensitiveReferenceError(buildStrictMessage(result), ruleFor(result), result.references, result.unresolvedScope);
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* True when the schema marks at least one table or column `sensitive`. Cheap pre-check
|
|
35
|
+
* for hosts (and `ask()`) that skip the guardrail entirely on schemas with no markers.
|
|
36
|
+
*/
|
|
37
|
+
export function schemaHasSensitiveIdentifiers(schema) {
|
|
38
|
+
return indexSchema(schema).hasSensitive;
|
|
39
|
+
}
|
|
40
|
+
/** Render a reference as `schema.table.column` (or `table.column` when the schema has no namespace). */
|
|
41
|
+
export function formatSensitiveReference(ref) {
|
|
42
|
+
const table = ref.schema ? `${ref.schema}.${ref.table}` : ref.table;
|
|
43
|
+
return `${table}.${ref.column}`;
|
|
44
|
+
}
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Strict-mode messaging
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
function ruleFor(result) {
|
|
49
|
+
if (result.references.some((r) => r.matchKind === "table"))
|
|
50
|
+
return "SENSITIVE_TABLE_REFERENCED";
|
|
51
|
+
if (result.references.length > 0)
|
|
52
|
+
return "SENSITIVE_COLUMN_REFERENCED";
|
|
53
|
+
return "UNRESOLVED_TABLE_SCOPE";
|
|
54
|
+
}
|
|
55
|
+
function buildStrictMessage(result) {
|
|
56
|
+
const parts = [];
|
|
57
|
+
if (result.references.length > 0) {
|
|
58
|
+
parts.push(`SQL references sensitive identifiers: ${result.references.map(formatSensitiveReference).join(", ")}`);
|
|
59
|
+
}
|
|
60
|
+
if (result.unresolvedScope)
|
|
61
|
+
parts.push(result.unresolvedScope.message);
|
|
62
|
+
return `Sensitive-identifier guardrail failed (strict mode): ${parts.join("; ")}`;
|
|
63
|
+
}
|
|
64
|
+
/** Loaded schemas are long-lived and re-used across calls; index once per object. */
|
|
65
|
+
const indexCache = new WeakMap();
|
|
66
|
+
function indexSchema(schema) {
|
|
67
|
+
const cached = indexCache.get(schema);
|
|
68
|
+
if (cached)
|
|
69
|
+
return cached;
|
|
70
|
+
const tables = [];
|
|
71
|
+
const byName = new Map();
|
|
72
|
+
let hasSensitive = false;
|
|
73
|
+
const rawTables = schema.tables;
|
|
74
|
+
rawTables.forEach((t, order) => {
|
|
75
|
+
const schemaName = typeof t.schema === "string" && t.schema !== "" ? t.schema : undefined;
|
|
76
|
+
const tableSensitive = t.sensitive === true;
|
|
77
|
+
if (tableSensitive)
|
|
78
|
+
hasSensitive = true;
|
|
79
|
+
const columns = (t.columns ?? []).map((c, ci) => {
|
|
80
|
+
const sensitive = tableSensitive || c.sensitive === true;
|
|
81
|
+
if (sensitive)
|
|
82
|
+
hasSensitive = true;
|
|
83
|
+
return { name: c.name, lower: c.name.toLowerCase(), sensitive, order: ci };
|
|
84
|
+
});
|
|
85
|
+
const entry = {
|
|
86
|
+
name: t.name,
|
|
87
|
+
...(schemaName ? { schema: schemaName } : {}),
|
|
88
|
+
lower: t.name.toLowerCase(),
|
|
89
|
+
...(schemaName ? { schemaLower: schemaName.toLowerCase() } : {}),
|
|
90
|
+
sensitive: tableSensitive,
|
|
91
|
+
order,
|
|
92
|
+
columns,
|
|
93
|
+
byColumn: new Map(columns.map((c) => [c.lower, c])),
|
|
94
|
+
};
|
|
95
|
+
tables.push(entry);
|
|
96
|
+
const bucket = byName.get(entry.lower);
|
|
97
|
+
if (bucket)
|
|
98
|
+
bucket.push(entry);
|
|
99
|
+
else
|
|
100
|
+
byName.set(entry.lower, [entry]);
|
|
101
|
+
});
|
|
102
|
+
const index = { tables, byName, hasSensitive };
|
|
103
|
+
indexCache.set(schema, index);
|
|
104
|
+
return index;
|
|
105
|
+
}
|
|
106
|
+
const WORD_START = /[A-Za-z_\u0080-\uFFFF]/;
|
|
107
|
+
const WORD_CHAR = /[A-Za-z0-9_$\u0080-\uFFFF]/;
|
|
108
|
+
function tokenize(sql) {
|
|
109
|
+
const out = [];
|
|
110
|
+
const push = (kind, value, quoted = false) => {
|
|
111
|
+
out.push({ kind, value, lower: value.toLowerCase(), quoted });
|
|
112
|
+
};
|
|
113
|
+
let i = 0;
|
|
114
|
+
while (i < sql.length) {
|
|
115
|
+
const ch = sql[i];
|
|
116
|
+
if (/\s/.test(ch)) {
|
|
117
|
+
i++;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (ch === "-" && sql[i + 1] === "-") {
|
|
121
|
+
while (i < sql.length && sql[i] !== "\n")
|
|
122
|
+
i++;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (ch === "/" && sql[i + 1] === "*") {
|
|
126
|
+
i += 2;
|
|
127
|
+
while (i < sql.length && !(sql[i] === "*" && sql[i + 1] === "/"))
|
|
128
|
+
i++;
|
|
129
|
+
i = Math.min(i + 2, sql.length);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (ch === "'") {
|
|
133
|
+
i++;
|
|
134
|
+
while (i < sql.length) {
|
|
135
|
+
if (sql[i] === "'" && sql[i + 1] === "'") {
|
|
136
|
+
i += 2;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (sql[i] === "'") {
|
|
140
|
+
i++;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
i++;
|
|
144
|
+
}
|
|
145
|
+
push("literal", "'");
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (ch === "$") {
|
|
149
|
+
const dollarQuote = /^\$(\w*)\$/.exec(sql.slice(i));
|
|
150
|
+
if (dollarQuote) {
|
|
151
|
+
const opener = dollarQuote[0];
|
|
152
|
+
const close = sql.indexOf(opener, i + opener.length);
|
|
153
|
+
i = close === -1 ? sql.length : close + opener.length;
|
|
154
|
+
push("literal", "$$");
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (/[0-9]/.test(sql[i + 1] ?? "")) {
|
|
158
|
+
let j = i + 1;
|
|
159
|
+
while (j < sql.length && /[0-9]/.test(sql[j]))
|
|
160
|
+
j++;
|
|
161
|
+
push("placeholder", sql.slice(i, j));
|
|
162
|
+
i = j;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (ch === '"' || ch === "`") {
|
|
167
|
+
const close = ch;
|
|
168
|
+
i++;
|
|
169
|
+
let buf = "";
|
|
170
|
+
while (i < sql.length) {
|
|
171
|
+
if (sql[i] === close && sql[i + 1] === close) {
|
|
172
|
+
buf += close;
|
|
173
|
+
i += 2;
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
if (sql[i] === close) {
|
|
177
|
+
i++;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
buf += sql[i];
|
|
181
|
+
i++;
|
|
182
|
+
}
|
|
183
|
+
push("word", buf, true);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (ch === "[") {
|
|
187
|
+
i++;
|
|
188
|
+
let buf = "";
|
|
189
|
+
while (i < sql.length && sql[i] !== "]") {
|
|
190
|
+
buf += sql[i];
|
|
191
|
+
i++;
|
|
192
|
+
}
|
|
193
|
+
if (i < sql.length)
|
|
194
|
+
i++;
|
|
195
|
+
push("word", buf, true);
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (ch === ":" && sql[i + 1] === ":") {
|
|
199
|
+
push("punct", "::");
|
|
200
|
+
i += 2;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if ((ch === ":" || ch === "@") && WORD_START.test(sql[i + 1] ?? "")) {
|
|
204
|
+
let j = i + 1;
|
|
205
|
+
while (j < sql.length && WORD_CHAR.test(sql[j]))
|
|
206
|
+
j++;
|
|
207
|
+
push("placeholder", sql.slice(i, j));
|
|
208
|
+
i = j;
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
if (/[0-9]/.test(ch)) {
|
|
212
|
+
let j = i;
|
|
213
|
+
while (j < sql.length && /[0-9]/.test(sql[j]))
|
|
214
|
+
j++;
|
|
215
|
+
if (sql[j] === "." && /[0-9]/.test(sql[j + 1] ?? "")) {
|
|
216
|
+
j++;
|
|
217
|
+
while (j < sql.length && /[0-9]/.test(sql[j]))
|
|
218
|
+
j++;
|
|
219
|
+
}
|
|
220
|
+
push("number", sql.slice(i, j));
|
|
221
|
+
i = j;
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
if (WORD_START.test(ch)) {
|
|
225
|
+
let j = i;
|
|
226
|
+
while (j < sql.length && WORD_CHAR.test(sql[j]))
|
|
227
|
+
j++;
|
|
228
|
+
push("word", sql.slice(i, j));
|
|
229
|
+
i = j;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
push("punct", ch);
|
|
233
|
+
i++;
|
|
234
|
+
}
|
|
235
|
+
return out;
|
|
236
|
+
}
|
|
237
|
+
// ---------------------------------------------------------------------------
|
|
238
|
+
// Keyword sets
|
|
239
|
+
// ---------------------------------------------------------------------------
|
|
240
|
+
/**
|
|
241
|
+
* Words that can never be a relation alias. Deliberately broad — a wrongly-taken
|
|
242
|
+
* "alias" would bind a qualifier to the wrong table.
|
|
243
|
+
*/
|
|
244
|
+
const ALIAS_STOP = new Set([
|
|
245
|
+
"all", "and", "any", "as", "asc", "at", "between", "by", "case", "collate", "cross",
|
|
246
|
+
"desc", "distinct", "else", "end", "escape", "except", "exists", "fetch", "filter",
|
|
247
|
+
"first", "for", "from", "full", "group", "having", "ilike", "in", "inner", "intersect",
|
|
248
|
+
"into", "is", "join", "last", "lateral", "left", "like", "limit", "natural", "next",
|
|
249
|
+
"not", "null", "nulls", "offset", "on", "only", "or", "order", "outer", "over",
|
|
250
|
+
"partition", "returning", "right", "rows", "select", "set", "similar", "some",
|
|
251
|
+
"straight_join", "tablesample", "then", "union", "unknown", "using", "values", "when",
|
|
252
|
+
"where", "window", "with", "within",
|
|
253
|
+
]);
|
|
254
|
+
/**
|
|
255
|
+
* Words that are never plausible column names, so they are excluded from the
|
|
256
|
+
* unqualified-candidate set. Deliberately *narrow* — words like `key`, `first`,
|
|
257
|
+
* `time`, `filter`, or `rows` are real column names in real schemas and must stay
|
|
258
|
+
* eligible so a sensitive column named `key` is still caught.
|
|
259
|
+
*/
|
|
260
|
+
const BARE_STOP = new Set([
|
|
261
|
+
"and", "as", "asc", "between", "by", "case", "cross", "desc", "distinct", "else",
|
|
262
|
+
"escape", "except", "exists", "false", "from", "group", "having", "ilike", "in",
|
|
263
|
+
"inner", "intersect", "is", "join", "lateral", "like", "limit", "natural", "not",
|
|
264
|
+
"null", "nulls", "offset", "on", "or", "order", "outer", "over", "partition",
|
|
265
|
+
"recursive", "select", "then", "true", "union", "using", "when", "where", "with",
|
|
266
|
+
]);
|
|
267
|
+
const JOIN_MODIFIER = new Set([
|
|
268
|
+
"inner", "left", "right", "full", "outer", "cross", "natural", "straight_join",
|
|
269
|
+
]);
|
|
270
|
+
function scan(sql, index) {
|
|
271
|
+
const tokens = tokenize(sql);
|
|
272
|
+
const isWord = (t) => t?.kind === "word";
|
|
273
|
+
const isPunct = (t, v) => t?.kind === "punct" && t.value === v;
|
|
274
|
+
const canAlias = (t) => t?.kind === "word" && (t.quoted || !ALIAS_STOP.has(t.lower));
|
|
275
|
+
/** Token indices already accounted for as relation names or aliases. */
|
|
276
|
+
const consumed = new Set();
|
|
277
|
+
/** Relation names that exist but are not schema tables (CTEs, derived tables). */
|
|
278
|
+
const derived = new Set();
|
|
279
|
+
const sourcePaths = [];
|
|
280
|
+
const aliasDecls = [];
|
|
281
|
+
let opaqueSource = false;
|
|
282
|
+
let sawTableSource = false;
|
|
283
|
+
const closeParenAfter = (open) => {
|
|
284
|
+
let depth = 0;
|
|
285
|
+
for (let k = open; k < tokens.length; k++) {
|
|
286
|
+
if (isPunct(tokens[k], "("))
|
|
287
|
+
depth++;
|
|
288
|
+
else if (isPunct(tokens[k], ")")) {
|
|
289
|
+
depth--;
|
|
290
|
+
if (depth === 0)
|
|
291
|
+
return k;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return -1;
|
|
295
|
+
};
|
|
296
|
+
const openParenBefore = (close) => {
|
|
297
|
+
let depth = 0;
|
|
298
|
+
for (let k = close; k >= 0; k--) {
|
|
299
|
+
if (isPunct(tokens[k], ")"))
|
|
300
|
+
depth++;
|
|
301
|
+
else if (isPunct(tokens[k], "(")) {
|
|
302
|
+
depth--;
|
|
303
|
+
if (depth === 0)
|
|
304
|
+
return k;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return -1;
|
|
308
|
+
};
|
|
309
|
+
/** Consume an optional `AS alias` / bare `alias`; returns the index after it. */
|
|
310
|
+
const takeAlias = (start, register) => {
|
|
311
|
+
let k = start;
|
|
312
|
+
if (isWord(tokens[k]) && tokens[k].lower === "as" && isWord(tokens[k + 1])) {
|
|
313
|
+
consumed.add(k);
|
|
314
|
+
k++;
|
|
315
|
+
}
|
|
316
|
+
if (canAlias(tokens[k])) {
|
|
317
|
+
register(tokens[k].lower);
|
|
318
|
+
consumed.add(k);
|
|
319
|
+
k++;
|
|
320
|
+
// Optional derived-column alias list: `… AS t(a, b)`
|
|
321
|
+
if (isPunct(tokens[k], "(")) {
|
|
322
|
+
const close = closeParenAfter(k);
|
|
323
|
+
if (close !== -1) {
|
|
324
|
+
for (let x = k + 1; x < close; x++)
|
|
325
|
+
if (isWord(tokens[x]))
|
|
326
|
+
consumed.add(x);
|
|
327
|
+
k = close + 1;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return k;
|
|
332
|
+
};
|
|
333
|
+
const parseTableRef = (start) => {
|
|
334
|
+
let j = start;
|
|
335
|
+
while (isWord(tokens[j]) && (tokens[j].lower === "lateral" || tokens[j].lower === "only")) {
|
|
336
|
+
consumed.add(j);
|
|
337
|
+
j++;
|
|
338
|
+
}
|
|
339
|
+
// Derived table / parenthesized join. The body is deliberately not skipped: the
|
|
340
|
+
// outer walk still visits its FROM/JOINs, so nested base tables land in scope too.
|
|
341
|
+
if (isPunct(tokens[j], "(")) {
|
|
342
|
+
const close = closeParenAfter(j);
|
|
343
|
+
if (close === -1)
|
|
344
|
+
return j + 1;
|
|
345
|
+
sawTableSource = true;
|
|
346
|
+
return takeAlias(close + 1, (alias) => derived.add(alias));
|
|
347
|
+
}
|
|
348
|
+
if (!canAlias(tokens[j])) {
|
|
349
|
+
// e.g. the operand in `EXTRACT(YEAR FROM 1)` — not a relation name.
|
|
350
|
+
return j;
|
|
351
|
+
}
|
|
352
|
+
const path = [];
|
|
353
|
+
const pathIdx = [];
|
|
354
|
+
let k = j;
|
|
355
|
+
for (;;) {
|
|
356
|
+
if (!isWord(tokens[k]))
|
|
357
|
+
break;
|
|
358
|
+
path.push(tokens[k].lower);
|
|
359
|
+
pathIdx.push(k);
|
|
360
|
+
k++;
|
|
361
|
+
if (isPunct(tokens[k], ".")) {
|
|
362
|
+
k++;
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
for (const x of pathIdx)
|
|
368
|
+
consumed.add(x);
|
|
369
|
+
if (isPunct(tokens[k], "(")) {
|
|
370
|
+
// Table function / table-valued expression — its columns are not schema columns.
|
|
371
|
+
opaqueSource = true;
|
|
372
|
+
const close = closeParenAfter(k);
|
|
373
|
+
return takeAlias(close === -1 ? k + 1 : close + 1, (alias) => derived.add(alias));
|
|
374
|
+
}
|
|
375
|
+
sawTableSource = true;
|
|
376
|
+
sourcePaths.push(path);
|
|
377
|
+
return takeAlias(k, (alias) => aliasDecls.push({ alias, path }));
|
|
378
|
+
};
|
|
379
|
+
// Pass A — resolve relation names, aliases, and CTE names.
|
|
380
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
381
|
+
const t = tokens[i];
|
|
382
|
+
if (t.kind !== "word" || t.quoted)
|
|
383
|
+
continue;
|
|
384
|
+
// `name AS (` / `name (cols) AS (` → CTE or named subquery.
|
|
385
|
+
if (t.lower === "as" && isPunct(tokens[i + 1], "(")) {
|
|
386
|
+
let back = i - 1;
|
|
387
|
+
if (isPunct(tokens[back], ")"))
|
|
388
|
+
back = openParenBefore(back) - 1;
|
|
389
|
+
if (canAlias(tokens[back])) {
|
|
390
|
+
derived.add(tokens[back].lower);
|
|
391
|
+
consumed.add(back);
|
|
392
|
+
}
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
if (t.lower !== "from" && t.lower !== "join")
|
|
396
|
+
continue;
|
|
397
|
+
consumed.add(i);
|
|
398
|
+
if (t.lower === "join") {
|
|
399
|
+
for (let k = i - 1; k >= 0 && isWord(tokens[k]) && JOIN_MODIFIER.has(tokens[k].lower); k--) {
|
|
400
|
+
consumed.add(k);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
let j = i + 1;
|
|
404
|
+
for (;;) {
|
|
405
|
+
const next = parseTableRef(j);
|
|
406
|
+
// Old-style comma-separated FROM lists; JOIN takes exactly one reference.
|
|
407
|
+
if (t.lower === "from" && next > j && isPunct(tokens[next], ",")) {
|
|
408
|
+
j = next + 1;
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
break;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
// Pass B — collect the column references the statement actually makes.
|
|
415
|
+
const qualifiedRefs = [];
|
|
416
|
+
const bare = new Set();
|
|
417
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
418
|
+
const t = tokens[i];
|
|
419
|
+
if (t.kind !== "word")
|
|
420
|
+
continue;
|
|
421
|
+
if (isPunct(tokens[i - 1], "."))
|
|
422
|
+
continue; // tail of a path, handled at its head
|
|
423
|
+
if (isPunct(tokens[i - 1], "::"))
|
|
424
|
+
continue; // cast target type
|
|
425
|
+
if (isWord(tokens[i - 1]) && tokens[i - 1].lower === "as")
|
|
426
|
+
continue; // output alias
|
|
427
|
+
if (isPunct(tokens[i + 1], ".")) {
|
|
428
|
+
const path = [t.lower];
|
|
429
|
+
let k = i + 1;
|
|
430
|
+
let star = false;
|
|
431
|
+
while (isPunct(tokens[k], ".")) {
|
|
432
|
+
k++;
|
|
433
|
+
if (isPunct(tokens[k], "*")) {
|
|
434
|
+
star = true;
|
|
435
|
+
k++;
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
if (!isWord(tokens[k]))
|
|
439
|
+
break;
|
|
440
|
+
path.push(tokens[k].lower);
|
|
441
|
+
k++;
|
|
442
|
+
}
|
|
443
|
+
if (!star && path.length >= 2 && !consumed.has(i)) {
|
|
444
|
+
qualifiedRefs.push({
|
|
445
|
+
column: path[path.length - 1],
|
|
446
|
+
qualifier: path[path.length - 2],
|
|
447
|
+
...(path.length >= 3 ? { qualifierSchema: path[path.length - 3] } : {}),
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
i = k - 1;
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
if (consumed.has(i))
|
|
454
|
+
continue;
|
|
455
|
+
if (isPunct(tokens[i + 1], "("))
|
|
456
|
+
continue; // function call
|
|
457
|
+
if (!t.quoted && BARE_STOP.has(t.lower))
|
|
458
|
+
continue;
|
|
459
|
+
bare.add(t.lower);
|
|
460
|
+
}
|
|
461
|
+
// Bind relation names and aliases to schema tables.
|
|
462
|
+
const resolve = (path) => {
|
|
463
|
+
const name = path[path.length - 1];
|
|
464
|
+
const qualifier = path.length >= 2 ? path[path.length - 2] : undefined;
|
|
465
|
+
const candidates = index.byName.get(name) ?? [];
|
|
466
|
+
if (!qualifier)
|
|
467
|
+
return candidates;
|
|
468
|
+
const exact = candidates.filter((e) => e.schemaLower === qualifier);
|
|
469
|
+
if (exact.length > 0)
|
|
470
|
+
return exact;
|
|
471
|
+
// v1 schemas carry no namespace — a qualified reference still matches by name.
|
|
472
|
+
return candidates.filter((e) => e.schemaLower === undefined);
|
|
473
|
+
};
|
|
474
|
+
const inScope = new Set();
|
|
475
|
+
const qualifiers = new Map();
|
|
476
|
+
const bindQualifier = (name, entries) => {
|
|
477
|
+
const bucket = qualifiers.get(name);
|
|
478
|
+
if (bucket)
|
|
479
|
+
bucket.push(...entries.filter((e) => !bucket.includes(e)));
|
|
480
|
+
else
|
|
481
|
+
qualifiers.set(name, [...entries]);
|
|
482
|
+
};
|
|
483
|
+
for (const path of sourcePaths) {
|
|
484
|
+
const entries = resolve(path);
|
|
485
|
+
for (const e of entries)
|
|
486
|
+
inScope.add(e);
|
|
487
|
+
bindQualifier(path[path.length - 1], entries);
|
|
488
|
+
}
|
|
489
|
+
for (const decl of aliasDecls)
|
|
490
|
+
bindQualifier(decl.alias, resolve(decl.path));
|
|
491
|
+
const found = new Map();
|
|
492
|
+
const record = (table, column, columnOrder, matchKind) => {
|
|
493
|
+
const key = `${table.schemaLower ?? ""}.${table.lower}.${column.toLowerCase()}`;
|
|
494
|
+
const existing = found.get(key);
|
|
495
|
+
if (existing) {
|
|
496
|
+
// A qualified hit is the stronger explanation of the same reference.
|
|
497
|
+
if (matchKind === "qualified")
|
|
498
|
+
existing.matchKind = "qualified";
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
found.set(key, {
|
|
502
|
+
table: table.name,
|
|
503
|
+
...(table.schema ? { schema: table.schema } : {}),
|
|
504
|
+
column,
|
|
505
|
+
matchKind,
|
|
506
|
+
tableOrder: table.order,
|
|
507
|
+
columnOrder,
|
|
508
|
+
});
|
|
509
|
+
};
|
|
510
|
+
// Sensitive tables reached as a FROM/JOIN target — catches `SELECT * FROM secrets`.
|
|
511
|
+
for (const table of inScope) {
|
|
512
|
+
if (table.sensitive)
|
|
513
|
+
record(table, "*", -1, "table");
|
|
514
|
+
}
|
|
515
|
+
const issues = new Set();
|
|
516
|
+
if (opaqueSource)
|
|
517
|
+
issues.add("OPAQUE_TABLE_SOURCE");
|
|
518
|
+
// Qualified references.
|
|
519
|
+
const unknownQualifierColumns = new Set();
|
|
520
|
+
for (const ref of qualifiedRefs) {
|
|
521
|
+
const bound = qualifiers.get(ref.qualifier);
|
|
522
|
+
if (!bound) {
|
|
523
|
+
if (derived.has(ref.qualifier))
|
|
524
|
+
continue; // CTE / derived relation — a known namespace
|
|
525
|
+
issues.add("UNKNOWN_QUALIFIER");
|
|
526
|
+
unknownQualifierColumns.add(ref.column);
|
|
527
|
+
continue;
|
|
528
|
+
}
|
|
529
|
+
const scoped = ref.qualifierSchema
|
|
530
|
+
? bound.filter((e) => e.schemaLower === undefined || e.schemaLower === ref.qualifierSchema)
|
|
531
|
+
: bound;
|
|
532
|
+
for (const table of scoped) {
|
|
533
|
+
const column = table.byColumn.get(ref.column);
|
|
534
|
+
if (column?.sensitive)
|
|
535
|
+
record(table, column.name, column.order, "qualified");
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
// Unqualified references — counted only when the owning table is in scope.
|
|
539
|
+
const noTableSource = !sawTableSource && bare.size > 0;
|
|
540
|
+
if (noTableSource)
|
|
541
|
+
issues.add("NO_TABLE_SOURCE");
|
|
542
|
+
const bareScope = noTableSource ? index.tables : [...inScope];
|
|
543
|
+
for (const table of bareScope) {
|
|
544
|
+
for (const column of table.columns) {
|
|
545
|
+
if (column.sensitive && bare.has(column.lower)) {
|
|
546
|
+
record(table, column.name, column.order, "unqualified");
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
// A qualifier we could not bind: its column could belong to anything, so match it
|
|
551
|
+
// against every sensitive column rather than drop it.
|
|
552
|
+
if (unknownQualifierColumns.size > 0) {
|
|
553
|
+
for (const table of index.tables) {
|
|
554
|
+
for (const column of table.columns) {
|
|
555
|
+
if (column.sensitive && unknownQualifierColumns.has(column.lower)) {
|
|
556
|
+
record(table, column.name, column.order, "unqualified");
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
const references = [...found.values()]
|
|
562
|
+
.sort((a, b) => a.tableOrder - b.tableOrder || a.columnOrder - b.columnOrder)
|
|
563
|
+
.map(({ tableOrder: _tableOrder, columnOrder: _columnOrder, ...ref }) => ref);
|
|
564
|
+
const unresolvedScope = issues.size > 0
|
|
565
|
+
? buildScopeReport([...issues], noTableSource || unknownQualifierColumns.size > 0)
|
|
566
|
+
: undefined;
|
|
567
|
+
return {
|
|
568
|
+
passed: references.length === 0 && unresolvedScope === undefined,
|
|
569
|
+
references,
|
|
570
|
+
...(unresolvedScope ? { unresolvedScope } : {}),
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
const SCOPE_ISSUE_TEXT = {
|
|
574
|
+
NO_TABLE_SOURCE: "no FROM/JOIN target could be resolved, so unqualified column names cannot be bound to a table",
|
|
575
|
+
UNKNOWN_QUALIFIER: "a qualified reference used a qualifier that is not a known table, alias, or CTE",
|
|
576
|
+
OPAQUE_TABLE_SOURCE: "a table source is not a relation name (table function or table-valued expression)",
|
|
577
|
+
};
|
|
578
|
+
function buildScopeReport(issues, widened) {
|
|
579
|
+
const detail = issues.map((i) => SCOPE_ISSUE_TEXT[i]).join("; ");
|
|
580
|
+
return {
|
|
581
|
+
issues,
|
|
582
|
+
widened,
|
|
583
|
+
message: `Could not resolve the statement's table scope: ${detail}.` +
|
|
584
|
+
(widened
|
|
585
|
+
? " Unqualified names were matched against every sensitive column in the schema, so some references may be over-reported."
|
|
586
|
+
: ""),
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
//# sourceMappingURL=sensitive-guardrail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sensitive-guardrail.js","sourceRoot":"","sources":["../../src/sql/sensitive-guardrail.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NormalizedTenantPolicy, TenantScope } from "../schema/v2/tenant-policy.js";
|
|
2
|
+
import type { DialectSpec } from "./dialect-spec.js";
|
|
2
3
|
export type TenantSqlOutputMode = "sql-only" | "sql-params";
|
|
3
4
|
export type TenantBinding = {
|
|
4
5
|
placeholder: string;
|
|
@@ -26,12 +27,12 @@ type ResolvedPlaceholder = {
|
|
|
26
27
|
ids: string[];
|
|
27
28
|
};
|
|
28
29
|
export declare function resolvePlaceholders(sql: string, policy: NormalizedTenantPolicy, scope: TenantScope): ResolvedPlaceholder[];
|
|
29
|
-
export declare function replacePlaceholdersWithLiterals(sql: string, resolved: ResolvedPlaceholder[]): string;
|
|
30
|
+
export declare function replacePlaceholdersWithLiterals(sql: string, resolved: ResolvedPlaceholder[], dialect?: Pick<DialectSpec, "backslashEscapes">): string;
|
|
30
31
|
export declare function replacePlaceholdersWithParams(sql: string, resolved: ResolvedPlaceholder[], startIndex?: number): {
|
|
31
32
|
sql: string;
|
|
32
33
|
params: unknown[];
|
|
33
34
|
nextIndex: number;
|
|
34
35
|
};
|
|
35
|
-
export declare function resolveTenantSql(sql: string, policy: NormalizedTenantPolicy, scope: TenantScope, mode?: TenantSqlOutputMode, paramStartIndex?: number): TenantPlaceholderResult;
|
|
36
|
+
export declare function resolveTenantSql(sql: string, policy: NormalizedTenantPolicy, scope: TenantScope, mode?: TenantSqlOutputMode, paramStartIndex?: number, dialect?: Pick<DialectSpec, "backslashEscapes">): TenantPlaceholderResult;
|
|
36
37
|
export {};
|
|
37
38
|
//# sourceMappingURL=tenant-placeholders.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenant-placeholders.d.ts","sourceRoot":"","sources":["../../src/sql/tenant-placeholders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,WAAW,EAEZ,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"tenant-placeholders.d.ts","sourceRoot":"","sources":["../../src/sql/tenant-placeholders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,WAAW,EAEZ,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAWrD,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,YAAY,CAAC;AAE5D,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,EAAE,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;CAAE,GAC5D;IACE,IAAI,EAAE,YAAY,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAMN,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExD;AAMD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAM/D;AAMD,KAAK,mBAAmB,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAErG,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,sBAAsB,EAC9B,KAAK,EAAE,WAAW,GACjB,mBAAmB,EAAE,CA2BvB;AAkCD,wBAAgB,+BAA+B,CAC7C,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,OAAO,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,GAC9C,MAAM,CAYR;AAMD,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,UAAU,GAAE,MAAU,GACrB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAqBvD;AAsCD,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,sBAAsB,EAC9B,KAAK,EAAE,WAAW,EAClB,IAAI,GAAE,mBAAgC,EACtC,eAAe,GAAE,MAAU,EAC3B,OAAO,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,GAC9C,uBAAuB,CA+BzB"}
|