@cyanheads/mcp-ts-core 0.8.11 → 0.8.12
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/CLAUDE.md +2 -1
- package/README.md +1 -1
- package/changelog/0.8.x/0.8.12.md +31 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +6 -1
- package/dist/config/index.js.map +1 -1
- package/dist/services/canvas/core/CanvasInstance.d.ts +3 -4
- package/dist/services/canvas/core/CanvasInstance.d.ts.map +1 -1
- package/dist/services/canvas/core/CanvasInstance.js +3 -4
- package/dist/services/canvas/core/CanvasInstance.js.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.d.ts +5 -11
- package/dist/services/canvas/core/CanvasRegistry.d.ts.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.js +5 -13
- package/dist/services/canvas/core/CanvasRegistry.js.map +1 -1
- package/dist/services/canvas/core/DataCanvas.d.ts +2 -3
- package/dist/services/canvas/core/DataCanvas.d.ts.map +1 -1
- package/dist/services/canvas/core/DataCanvas.js +3 -8
- package/dist/services/canvas/core/DataCanvas.js.map +1 -1
- package/dist/services/canvas/core/IDataCanvasProvider.d.ts +4 -4
- package/dist/services/canvas/core/IDataCanvasProvider.js +4 -4
- package/dist/services/canvas/core/canvasFactory.d.ts +7 -15
- package/dist/services/canvas/core/canvasFactory.d.ts.map +1 -1
- package/dist/services/canvas/core/canvasFactory.js +7 -16
- package/dist/services/canvas/core/canvasFactory.js.map +1 -1
- package/dist/services/canvas/core/sqlGate.d.ts +81 -57
- package/dist/services/canvas/core/sqlGate.d.ts.map +1 -1
- package/dist/services/canvas/core/sqlGate.js +199 -80
- package/dist/services/canvas/core/sqlGate.js.map +1 -1
- package/dist/services/canvas/index.d.ts +1 -1
- package/dist/services/canvas/index.d.ts.map +1 -1
- package/dist/services/canvas/index.js +1 -1
- package/dist/services/canvas/index.js.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts +38 -16
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js +205 -189
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js.map +1 -1
- package/dist/services/canvas/providers/duckdb/exportWriter.d.ts +13 -25
- package/dist/services/canvas/providers/duckdb/exportWriter.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/exportWriter.js +15 -29
- package/dist/services/canvas/providers/duckdb/exportWriter.js.map +1 -1
- package/dist/services/canvas/providers/duckdb/schemaSniffer.d.ts +19 -26
- package/dist/services/canvas/providers/duckdb/schemaSniffer.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/schemaSniffer.js +30 -56
- package/dist/services/canvas/providers/duckdb/schemaSniffer.js.map +1 -1
- package/dist/services/canvas/types.d.ts +1 -2
- package/dist/services/canvas/types.d.ts.map +1 -1
- package/dist/services/canvas/types.js +1 -2
- package/dist/services/canvas/types.js.map +1 -1
- package/dist/utils/internal/requestContext.d.ts +9 -4
- package/dist/utils/internal/requestContext.d.ts.map +1 -1
- package/dist/utils/internal/requestContext.js.map +1 -1
- package/package.json +2 -2
- package/dist/logs/combined.log +0 -4
- package/dist/logs/error.log +0 -4
- package/dist/logs/interactions.log +0 -0
|
@@ -1,50 +1,56 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Read-only SQL gate for the DataCanvas primitive. Engine-agnostic
|
|
3
|
-
* pure validators
|
|
4
|
-
* metadata (statement extraction, prepared-statement type, EXPLAIN plan JSON).
|
|
3
|
+
* pure validators the provider invokes after pulling DuckDB-specific metadata.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
5
|
+
* Four layers of enforcement, each authoritative:
|
|
7
6
|
*
|
|
8
|
-
* 1. **
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* 2. **
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
7
|
+
* 1. **Function deny-list (text scan).** Pre-EXPLAIN regex against the SQL
|
|
8
|
+
* (string literals stripped) for file/HTTP-reading table functions like
|
|
9
|
+
* `read_json`, `read_parquet`. These can lower into generic SEQ_SCAN
|
|
10
|
+
* operators that pass the operator allowlist; catching them by name closes
|
|
11
|
+
* that bypass.
|
|
12
|
+
* 2. **Single-statement check.** Reject anything other than exactly one
|
|
13
|
+
* statement parsed by DuckDB. Comment-hidden second statements, Unicode
|
|
14
|
+
* tricks, and multi-statement smuggling collapse here.
|
|
15
|
+
* 3. **Statement-type check.** Require `SELECT`. DDL, DML, and utility
|
|
16
|
+
* statements (PRAGMA/ATTACH/COPY/INSTALL/LOAD/SET/EXECUTE) fail to type as
|
|
17
|
+
* SELECT.
|
|
18
|
+
* 4. **Plan-walk allowlist + denied-function rescan.** Walk the
|
|
19
|
+
* `EXPLAIN (FORMAT JSON)` tree; reject any operator outside the allowlist
|
|
20
|
+
* or any string field referencing a deny-listed function.
|
|
21
21
|
*
|
|
22
|
-
* Rejection paths throw `ValidationError` with a structured `data.reason
|
|
23
|
-
* suitable for surfacing to the agent.
|
|
22
|
+
* Rejection paths throw `ValidationError` with a structured `data.reason`.
|
|
24
23
|
*
|
|
25
24
|
* @module src/services/canvas/core/sqlGate
|
|
26
25
|
*/
|
|
27
26
|
/**
|
|
28
|
-
* DuckDB statement-type
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* `INSTALL`, `SET`, `RESET`, `EXECUTE`, `EXPLAIN`, `TRANSACTION`, `VACUUM`,
|
|
32
|
-
* `CHECKPOINT`, `CALL`, …) are rejected outright. This is a surface — not
|
|
33
|
-
* an enum we own — so the gate matches on the literal string emitted.
|
|
27
|
+
* DuckDB statement-type string. Only `SELECT` is accepted; everything else
|
|
28
|
+
* (DDL, DML, utility) is rejected. Modeled as a string surface rather than an
|
|
29
|
+
* owned enum so the gate matches on whatever DuckDB emits.
|
|
34
30
|
*/
|
|
35
31
|
export type DuckdbStatementType = string;
|
|
36
32
|
/** Subset of statement types the gate permits. */
|
|
37
33
|
export declare const ALLOWED_STATEMENT_TYPES: ReadonlySet<DuckdbStatementType>;
|
|
38
34
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
35
|
+
* Reason codes set on `validationError.data.reason` by gate assertions.
|
|
36
|
+
* Consumers can import the {@link SqlGateReason} union to translate gate
|
|
37
|
+
* denials into typed contract reasons without duplicating the strings.
|
|
38
|
+
*/
|
|
39
|
+
export declare const SQL_GATE_REASONS: {
|
|
40
|
+
readonly multiStatement: "multi_statement";
|
|
41
|
+
readonly nonSelectStatement: "non_select_statement";
|
|
42
|
+
readonly planOperatorNotAllowed: "plan_operator_not_allowed";
|
|
43
|
+
readonly deniedFunction: "denied_function";
|
|
44
|
+
readonly deniedFunctionInPlan: "denied_function_in_plan";
|
|
45
|
+
readonly identifierEmpty: "identifier_empty";
|
|
46
|
+
readonly identifierShape: "identifier_shape";
|
|
47
|
+
readonly identifierReserved: "identifier_reserved";
|
|
48
|
+
};
|
|
49
|
+
/** Union of all gate reason strings — see {@link SQL_GATE_REASONS}. */
|
|
50
|
+
export type SqlGateReason = (typeof SQL_GATE_REASONS)[keyof typeof SQL_GATE_REASONS];
|
|
51
|
+
/**
|
|
52
|
+
* Allowlist of read-only operator names that can appear in an EXPLAIN plan.
|
|
53
|
+
* Anything outside this set causes rejection. Notable exclusions:
|
|
48
54
|
*
|
|
49
55
|
* - `READ_CSV`, `READ_PARQUET`, `READ_JSON` — bypass canvas, read external files.
|
|
50
56
|
* - `INSERT`, `UPDATE`, `DELETE`, `MERGE`, `CREATE_*`, `DROP_*`, `ALTER_*` — writes.
|
|
@@ -53,9 +59,21 @@ export declare const ALLOWED_STATEMENT_TYPES: ReadonlySet<DuckdbStatementType>;
|
|
|
53
59
|
*/
|
|
54
60
|
export declare const ALLOWED_PLAN_OPERATORS: ReadonlySet<string>;
|
|
55
61
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
62
|
+
* External-data table functions (files, HTTP, S3, lakehouse formats). These
|
|
63
|
+
* lower into generic scan operators that pass the operator allowlist, so the
|
|
64
|
+
* text-scan and plan-rescan defenses in this module catch them by name
|
|
65
|
+
* regardless of how DuckDB lowers them.
|
|
66
|
+
*/
|
|
67
|
+
export declare const DENIED_TABLE_FUNCTIONS: ReadonlySet<string>;
|
|
68
|
+
/**
|
|
69
|
+
* Layer 1: pre-EXPLAIN function deny-list. Scans the SQL (string literals
|
|
70
|
+
* stripped) for calls to any function in {@link DENIED_TABLE_FUNCTIONS} so a
|
|
71
|
+
* malicious `read_json('/etc/passwd')` is rejected before reaching the planner.
|
|
72
|
+
*/
|
|
73
|
+
export declare function assertNoDeniedFunctions(sql: string): void;
|
|
74
|
+
/**
|
|
75
|
+
* Layers 2-4. Throws on the first violation. Layer 1
|
|
76
|
+
* ({@link assertNoDeniedFunctions}) runs separately before `extractStatements`.
|
|
59
77
|
*/
|
|
60
78
|
export declare function assertReadOnlyQuery(input: {
|
|
61
79
|
/** Number of statements DuckDB extracted from the user-supplied SQL. */
|
|
@@ -66,42 +84,48 @@ export declare function assertReadOnlyQuery(input: {
|
|
|
66
84
|
planJson: unknown;
|
|
67
85
|
}): void;
|
|
68
86
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* here rather than a confusing parser error from EXPLAIN itself.
|
|
87
|
+
* Layers 2-3: validate statement count and type before EXPLAIN. Non-SELECT
|
|
88
|
+
* statements (ATTACH/PRAGMA/COPY/INSTALL/...) fail here with a structured
|
|
89
|
+
* ValidationError rather than a confusing parser error from EXPLAIN itself.
|
|
73
90
|
*/
|
|
74
91
|
export declare function assertSelectOnly(input: {
|
|
75
92
|
statementCount: number;
|
|
76
93
|
statementType: DuckdbStatementType;
|
|
77
94
|
}): void;
|
|
78
95
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* smuggle work into a SELECT envelope.
|
|
96
|
+
* Layer 4: walk the plan tree and reject any operator outside the allowlist
|
|
97
|
+
* or any deny-listed table function smuggled into a generic scan operator.
|
|
82
98
|
*/
|
|
83
99
|
export declare function assertPlanReadOnly(planJson: unknown): void;
|
|
84
100
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* Tolerant of structural variation — DuckDB emits operator identity under
|
|
90
|
-
* either `name` (logical plan) or `operator_type` (physical/profile plan)
|
|
91
|
-
* depending on the EXPLAIN flavor. We honor both. Children traversal
|
|
92
|
-
* supports `children`, `child`, and `inputs` arrays.
|
|
101
|
+
* Returns operator names not in `ALLOWED_PLAN_OPERATORS`. Exported for
|
|
102
|
+
* fixture-driven tests that want to inspect the gate's view without throwing.
|
|
103
|
+
* Use {@link collectPlanViolations} to also surface deny-listed function
|
|
104
|
+
* references in scan-operator metadata.
|
|
93
105
|
*/
|
|
94
106
|
export declare function collectDisallowedOperators(planJson: unknown): Set<string>;
|
|
95
107
|
/**
|
|
96
|
-
*
|
|
97
|
-
*
|
|
108
|
+
* Combined plan-walk: disallowed operators and deny-listed table-function
|
|
109
|
+
* references in string-valued fields, returned separately so callers can word
|
|
110
|
+
* errors appropriately.
|
|
111
|
+
*/
|
|
112
|
+
export declare function collectPlanViolations(planJson: unknown): {
|
|
113
|
+
offending: Set<string>;
|
|
114
|
+
deniedFunctions: Set<string>;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Allowed shape for canvas table/column names. SQL identifier convention:
|
|
118
|
+
* letter/underscore start, letters/digits/underscores after, max 63 chars
|
|
119
|
+
* (PostgreSQL/DuckDB cap). Exported so consumers can reuse it in Zod schemas
|
|
120
|
+
* (`z.string().regex(CANVAS_IDENTIFIER_REGEX)`).
|
|
98
121
|
*/
|
|
122
|
+
export declare const CANVAS_IDENTIFIER_REGEX: RegExp;
|
|
123
|
+
/** Validate a canvas table or column name. Throws `ValidationError` on rejection. */
|
|
99
124
|
export declare function assertValidIdentifier(value: string, kind: 'table' | 'column'): void;
|
|
100
125
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* only escapes; it does not validate shape.
|
|
126
|
+
* Double-quote-escape an identifier for SQL embedding. Validate via
|
|
127
|
+
* {@link assertValidIdentifier} first — this helper only escapes, it does not
|
|
128
|
+
* check shape.
|
|
105
129
|
*/
|
|
106
130
|
export declare function quoteIdentifier(value: string): string;
|
|
107
131
|
//# sourceMappingURL=sqlGate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlGate.d.ts","sourceRoot":"","sources":["../../../../src/services/canvas/core/sqlGate.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sqlGate.d.ts","sourceRoot":"","sources":["../../../../src/services/canvas/core/sqlGate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAEzC,kDAAkD;AAClD,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,mBAAmB,CAAuB,CAAC;AAE7F;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;CASnB,CAAC;AAEX,uEAAuE;AACvE,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC;AAErF;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAwDrD,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAoCrD,CAAC;AA4CH;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAYzD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,wEAAwE;IACxE,cAAc,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,aAAa,EAAE,mBAAmB,CAAC;IACnC,8CAA8C;IAC9C,QAAQ,EAAE,OAAO,CAAC;CACnB,GAAG,IAAI,CAGP;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,mBAAmB,CAAC;CACpC,GAAG,IAAI,CAaP;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAoB1D;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAEzE;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,GAAG;IACxD,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC9B,CAKA;AAmDD;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,QAAkC,CAAC;AA6CvE,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAmBnF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD"}
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Read-only SQL gate for the DataCanvas primitive. Engine-agnostic
|
|
3
|
-
* pure validators
|
|
4
|
-
* metadata (statement extraction, prepared-statement type, EXPLAIN plan JSON).
|
|
3
|
+
* pure validators the provider invokes after pulling DuckDB-specific metadata.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
5
|
+
* Four layers of enforcement, each authoritative:
|
|
7
6
|
*
|
|
8
|
-
* 1. **
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* 2. **
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
7
|
+
* 1. **Function deny-list (text scan).** Pre-EXPLAIN regex against the SQL
|
|
8
|
+
* (string literals stripped) for file/HTTP-reading table functions like
|
|
9
|
+
* `read_json`, `read_parquet`. These can lower into generic SEQ_SCAN
|
|
10
|
+
* operators that pass the operator allowlist; catching them by name closes
|
|
11
|
+
* that bypass.
|
|
12
|
+
* 2. **Single-statement check.** Reject anything other than exactly one
|
|
13
|
+
* statement parsed by DuckDB. Comment-hidden second statements, Unicode
|
|
14
|
+
* tricks, and multi-statement smuggling collapse here.
|
|
15
|
+
* 3. **Statement-type check.** Require `SELECT`. DDL, DML, and utility
|
|
16
|
+
* statements (PRAGMA/ATTACH/COPY/INSTALL/LOAD/SET/EXECUTE) fail to type as
|
|
17
|
+
* SELECT.
|
|
18
|
+
* 4. **Plan-walk allowlist + denied-function rescan.** Walk the
|
|
19
|
+
* `EXPLAIN (FORMAT JSON)` tree; reject any operator outside the allowlist
|
|
20
|
+
* or any string field referencing a deny-listed function.
|
|
21
21
|
*
|
|
22
|
-
* Rejection paths throw `ValidationError` with a structured `data.reason
|
|
23
|
-
* suitable for surfacing to the agent.
|
|
22
|
+
* Rejection paths throw `ValidationError` with a structured `data.reason`.
|
|
24
23
|
*
|
|
25
24
|
* @module src/services/canvas/core/sqlGate
|
|
26
25
|
*/
|
|
@@ -28,15 +27,23 @@ import { validationError } from '../../../types-global/errors.js';
|
|
|
28
27
|
/** Subset of statement types the gate permits. */
|
|
29
28
|
export const ALLOWED_STATEMENT_TYPES = new Set(['SELECT']);
|
|
30
29
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
30
|
+
* Reason codes set on `validationError.data.reason` by gate assertions.
|
|
31
|
+
* Consumers can import the {@link SqlGateReason} union to translate gate
|
|
32
|
+
* denials into typed contract reasons without duplicating the strings.
|
|
33
|
+
*/
|
|
34
|
+
export const SQL_GATE_REASONS = {
|
|
35
|
+
multiStatement: 'multi_statement',
|
|
36
|
+
nonSelectStatement: 'non_select_statement',
|
|
37
|
+
planOperatorNotAllowed: 'plan_operator_not_allowed',
|
|
38
|
+
deniedFunction: 'denied_function',
|
|
39
|
+
deniedFunctionInPlan: 'denied_function_in_plan',
|
|
40
|
+
identifierEmpty: 'identifier_empty',
|
|
41
|
+
identifierShape: 'identifier_shape',
|
|
42
|
+
identifierReserved: 'identifier_reserved',
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Allowlist of read-only operator names that can appear in an EXPLAIN plan.
|
|
46
|
+
* Anything outside this set causes rejection. Notable exclusions:
|
|
40
47
|
*
|
|
41
48
|
* - `READ_CSV`, `READ_PARQUET`, `READ_JSON` — bypass canvas, read external files.
|
|
42
49
|
* - `INSERT`, `UPDATE`, `DELETE`, `MERGE`, `CREATE_*`, `DROP_*`, `ALTER_*` — writes.
|
|
@@ -44,7 +51,7 @@ export const ALLOWED_STATEMENT_TYPES = new Set(['SELECT']);
|
|
|
44
51
|
* - `ATTACH`, `DETACH`, `LOAD`, `INSTALL`, `PRAGMA`, `SET`, `RESET` — utility.
|
|
45
52
|
*/
|
|
46
53
|
export const ALLOWED_PLAN_OPERATORS = new Set([
|
|
47
|
-
// Scans (registered tables only
|
|
54
|
+
// Scans (registered tables only)
|
|
48
55
|
'SEQ_SCAN',
|
|
49
56
|
'COLUMN_DATA_SCAN',
|
|
50
57
|
'CHUNK_SCAN',
|
|
@@ -101,66 +108,164 @@ export const ALLOWED_PLAN_OPERATORS = new Set([
|
|
|
101
108
|
'PIVOT',
|
|
102
109
|
]);
|
|
103
110
|
/**
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
111
|
+
* External-data table functions (files, HTTP, S3, lakehouse formats). These
|
|
112
|
+
* lower into generic scan operators that pass the operator allowlist, so the
|
|
113
|
+
* text-scan and plan-rescan defenses in this module catch them by name
|
|
114
|
+
* regardless of how DuckDB lowers them.
|
|
115
|
+
*/
|
|
116
|
+
export const DENIED_TABLE_FUNCTIONS = new Set([
|
|
117
|
+
// CSV
|
|
118
|
+
'read_csv',
|
|
119
|
+
'read_csv_auto',
|
|
120
|
+
'sniff_csv',
|
|
121
|
+
// JSON
|
|
122
|
+
'read_json',
|
|
123
|
+
'read_json_auto',
|
|
124
|
+
'read_json_objects',
|
|
125
|
+
'read_json_objects_auto',
|
|
126
|
+
'read_ndjson',
|
|
127
|
+
'read_ndjson_auto',
|
|
128
|
+
'read_ndjson_objects',
|
|
129
|
+
// Parquet
|
|
130
|
+
'read_parquet',
|
|
131
|
+
'parquet_scan',
|
|
132
|
+
'parquet_metadata',
|
|
133
|
+
'parquet_schema',
|
|
134
|
+
'parquet_file_metadata',
|
|
135
|
+
'parquet_kv_metadata',
|
|
136
|
+
// Text / blob / glob
|
|
137
|
+
'read_text',
|
|
138
|
+
'read_blob',
|
|
139
|
+
'glob',
|
|
140
|
+
// Iceberg / Delta
|
|
141
|
+
'iceberg_scan',
|
|
142
|
+
'iceberg_metadata',
|
|
143
|
+
'iceberg_snapshots',
|
|
144
|
+
'delta_scan',
|
|
145
|
+
// Postgres / MySQL / SQLite scanners (extension-loaded; defense-in-depth)
|
|
146
|
+
'postgres_scan',
|
|
147
|
+
'postgres_query',
|
|
148
|
+
'mysql_scan',
|
|
149
|
+
'mysql_query',
|
|
150
|
+
'sqlite_scan',
|
|
151
|
+
'sqlite_query',
|
|
152
|
+
]);
|
|
153
|
+
/**
|
|
154
|
+
* Call-shape regex (`name(`). Caller strips comments and string literals first
|
|
155
|
+
* so quoted text and comment-injected separators between a name and its `(`
|
|
156
|
+
* can't false-positive or bypass.
|
|
157
|
+
*/
|
|
158
|
+
const DENIED_FUNCTION_CALL_REGEX = new RegExp(String.raw `\b(${[...DENIED_TABLE_FUNCTIONS].join('|')})\s*\(`, 'gi');
|
|
159
|
+
/**
|
|
160
|
+
* Bare-name regex for the plan-walk rescan only. DuckDB EXPLAIN metadata can
|
|
161
|
+
* spell out a function as `Function: read_json` without parens. Restricted to
|
|
162
|
+
* known function-name fields to avoid scanning user-projected string literals.
|
|
163
|
+
*/
|
|
164
|
+
const DENIED_FUNCTION_BARE_REGEX = new RegExp(String.raw `\b(${[...DENIED_TABLE_FUNCTIONS].join('|')})\b`, 'gi');
|
|
165
|
+
/** Plan-node string fields where DuckDB stores lowered table-function names. */
|
|
166
|
+
const FUNCTION_METADATA_KEYS = new Set([
|
|
167
|
+
'extra_info',
|
|
168
|
+
'function',
|
|
169
|
+
'function_name',
|
|
170
|
+
'table_function',
|
|
171
|
+
'source',
|
|
172
|
+
]);
|
|
173
|
+
/** Strip SQL block and line comments. */
|
|
174
|
+
function stripSqlComments(sql) {
|
|
175
|
+
return sql.replace(/\/\*[\s\S]*?\*\//g, ' ').replace(/--[^\n]*/g, '');
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Strip standard SQL string literals. Doesn't handle E-strings or DuckDB
|
|
179
|
+
* dollar-quoting; the plan-walk rescan catches anything that survives.
|
|
180
|
+
*/
|
|
181
|
+
function stripSqlStringLiterals(sql) {
|
|
182
|
+
return sql.replace(/'(?:[^']|'')*'/g, "''");
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Layer 1: pre-EXPLAIN function deny-list. Scans the SQL (string literals
|
|
186
|
+
* stripped) for calls to any function in {@link DENIED_TABLE_FUNCTIONS} so a
|
|
187
|
+
* malicious `read_json('/etc/passwd')` is rejected before reaching the planner.
|
|
188
|
+
*/
|
|
189
|
+
export function assertNoDeniedFunctions(sql) {
|
|
190
|
+
if (typeof sql !== 'string' || sql.length === 0)
|
|
191
|
+
return;
|
|
192
|
+
const stripped = stripSqlStringLiterals(stripSqlComments(sql));
|
|
193
|
+
DENIED_FUNCTION_CALL_REGEX.lastIndex = 0;
|
|
194
|
+
const match = DENIED_FUNCTION_CALL_REGEX.exec(stripped);
|
|
195
|
+
if (match?.[1]) {
|
|
196
|
+
const fn = match[1].toLowerCase();
|
|
197
|
+
throw validationError(`Canvas query references disallowed table function: ${fn}. File-reading and external-data functions are not permitted.`, { reason: SQL_GATE_REASONS.deniedFunction, function: fn });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Layers 2-4. Throws on the first violation. Layer 1
|
|
202
|
+
* ({@link assertNoDeniedFunctions}) runs separately before `extractStatements`.
|
|
107
203
|
*/
|
|
108
204
|
export function assertReadOnlyQuery(input) {
|
|
109
205
|
assertSelectOnly(input);
|
|
110
206
|
assertPlanReadOnly(input.planJson);
|
|
111
207
|
}
|
|
112
208
|
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
* here rather than a confusing parser error from EXPLAIN itself.
|
|
209
|
+
* Layers 2-3: validate statement count and type before EXPLAIN. Non-SELECT
|
|
210
|
+
* statements (ATTACH/PRAGMA/COPY/INSTALL/...) fail here with a structured
|
|
211
|
+
* ValidationError rather than a confusing parser error from EXPLAIN itself.
|
|
117
212
|
*/
|
|
118
213
|
export function assertSelectOnly(input) {
|
|
119
214
|
if (input.statementCount !== 1) {
|
|
120
215
|
throw validationError('Canvas query must contain exactly one SQL statement.', {
|
|
121
|
-
reason:
|
|
216
|
+
reason: SQL_GATE_REASONS.multiStatement,
|
|
122
217
|
statementCount: input.statementCount,
|
|
123
218
|
});
|
|
124
219
|
}
|
|
125
220
|
if (!ALLOWED_STATEMENT_TYPES.has(input.statementType)) {
|
|
126
|
-
throw validationError(`Canvas query must be SELECT; got ${input.statementType}. Mutations must use registerTable, drop, or clear.`, { reason:
|
|
221
|
+
throw validationError(`Canvas query must be SELECT; got ${input.statementType}. Mutations must use registerTable, drop, or clear.`, { reason: SQL_GATE_REASONS.nonSelectStatement, statementType: input.statementType });
|
|
127
222
|
}
|
|
128
223
|
}
|
|
129
224
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
* smuggle work into a SELECT envelope.
|
|
225
|
+
* Layer 4: walk the plan tree and reject any operator outside the allowlist
|
|
226
|
+
* or any deny-listed table function smuggled into a generic scan operator.
|
|
133
227
|
*/
|
|
134
228
|
export function assertPlanReadOnly(planJson) {
|
|
135
|
-
const offending =
|
|
229
|
+
const { offending, deniedFunctions } = collectPlanViolations(planJson);
|
|
230
|
+
if (deniedFunctions.size > 0) {
|
|
231
|
+
throw validationError(`Canvas query references disallowed table function in plan: ${[...deniedFunctions].sort().join(', ')}.`, {
|
|
232
|
+
reason: SQL_GATE_REASONS.deniedFunctionInPlan,
|
|
233
|
+
functions: [...deniedFunctions].sort(),
|
|
234
|
+
});
|
|
235
|
+
}
|
|
136
236
|
if (offending.size > 0) {
|
|
137
237
|
throw validationError(`Canvas query contains disallowed operators: ${[...offending].sort().join(', ')}.`, {
|
|
138
|
-
reason:
|
|
238
|
+
reason: SQL_GATE_REASONS.planOperatorNotAllowed,
|
|
139
239
|
operators: [...offending].sort(),
|
|
140
240
|
});
|
|
141
241
|
}
|
|
142
242
|
}
|
|
143
243
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
* Tolerant of structural variation — DuckDB emits operator identity under
|
|
149
|
-
* either `name` (logical plan) or `operator_type` (physical/profile plan)
|
|
150
|
-
* depending on the EXPLAIN flavor. We honor both. Children traversal
|
|
151
|
-
* supports `children`, `child`, and `inputs` arrays.
|
|
244
|
+
* Returns operator names not in `ALLOWED_PLAN_OPERATORS`. Exported for
|
|
245
|
+
* fixture-driven tests that want to inspect the gate's view without throwing.
|
|
246
|
+
* Use {@link collectPlanViolations} to also surface deny-listed function
|
|
247
|
+
* references in scan-operator metadata.
|
|
152
248
|
*/
|
|
153
249
|
export function collectDisallowedOperators(planJson) {
|
|
250
|
+
return collectPlanViolations(planJson).offending;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Combined plan-walk: disallowed operators and deny-listed table-function
|
|
254
|
+
* references in string-valued fields, returned separately so callers can word
|
|
255
|
+
* errors appropriately.
|
|
256
|
+
*/
|
|
257
|
+
export function collectPlanViolations(planJson) {
|
|
154
258
|
const offending = new Set();
|
|
155
|
-
|
|
156
|
-
|
|
259
|
+
const deniedFunctions = new Set();
|
|
260
|
+
walk(planJson, offending, deniedFunctions);
|
|
261
|
+
return { offending, deniedFunctions };
|
|
157
262
|
}
|
|
158
|
-
function walk(node, offending) {
|
|
263
|
+
function walk(node, offending, deniedFunctions) {
|
|
159
264
|
if (node === null || typeof node !== 'object')
|
|
160
265
|
return;
|
|
161
266
|
if (Array.isArray(node)) {
|
|
162
267
|
for (const child of node)
|
|
163
|
-
walk(child, offending);
|
|
268
|
+
walk(child, offending, deniedFunctions);
|
|
164
269
|
return;
|
|
165
270
|
}
|
|
166
271
|
const obj = node;
|
|
@@ -168,19 +273,38 @@ function walk(node, offending) {
|
|
|
168
273
|
if (operator !== undefined && !ALLOWED_PLAN_OPERATORS.has(operator)) {
|
|
169
274
|
offending.add(operator);
|
|
170
275
|
}
|
|
171
|
-
//
|
|
276
|
+
// read_json/read_parquet lower into generic scan operators whose source
|
|
277
|
+
// function appears in plan metadata, not the operator name. Use the bare
|
|
278
|
+
// regex on known function-name fields, the call-shape regex elsewhere.
|
|
279
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
280
|
+
if (typeof value !== 'string')
|
|
281
|
+
continue;
|
|
282
|
+
const regex = FUNCTION_METADATA_KEYS.has(key)
|
|
283
|
+
? DENIED_FUNCTION_BARE_REGEX
|
|
284
|
+
: DENIED_FUNCTION_CALL_REGEX;
|
|
285
|
+
collectDeniedFunctionMatches(value, regex, deniedFunctions);
|
|
286
|
+
}
|
|
172
287
|
for (const key of ['children', 'child', 'inputs', 'plan', 'root']) {
|
|
173
288
|
if (key in obj)
|
|
174
|
-
walk(obj[key], offending);
|
|
289
|
+
walk(obj[key], offending, deniedFunctions);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function collectDeniedFunctionMatches(value, regex, sink) {
|
|
293
|
+
regex.lastIndex = 0;
|
|
294
|
+
let match = regex.exec(value);
|
|
295
|
+
while (match !== null) {
|
|
296
|
+
if (match[1])
|
|
297
|
+
sink.add(match[1].toLowerCase());
|
|
298
|
+
match = regex.exec(value);
|
|
175
299
|
}
|
|
176
300
|
}
|
|
177
301
|
function readOperatorName(obj) {
|
|
178
|
-
|
|
179
|
-
|
|
302
|
+
// DuckDB emits operator identity under different keys depending on the
|
|
303
|
+
// EXPLAIN flavor (logical/physical/profile).
|
|
304
|
+
for (const key of ['name', 'operator_type', 'operator', 'type']) {
|
|
180
305
|
const value = obj[key];
|
|
181
|
-
if (typeof value === 'string' && value !== '')
|
|
306
|
+
if (typeof value === 'string' && value !== '')
|
|
182
307
|
return value.toUpperCase();
|
|
183
|
-
}
|
|
184
308
|
}
|
|
185
309
|
return;
|
|
186
310
|
}
|
|
@@ -188,16 +312,15 @@ function readOperatorName(obj) {
|
|
|
188
312
|
// Identifier validation and quoting
|
|
189
313
|
// ---------------------------------------------------------------------------
|
|
190
314
|
/**
|
|
191
|
-
* Allowed shape for canvas
|
|
192
|
-
*
|
|
193
|
-
*
|
|
315
|
+
* Allowed shape for canvas table/column names. SQL identifier convention:
|
|
316
|
+
* letter/underscore start, letters/digits/underscores after, max 63 chars
|
|
317
|
+
* (PostgreSQL/DuckDB cap). Exported so consumers can reuse it in Zod schemas
|
|
318
|
+
* (`z.string().regex(CANVAS_IDENTIFIER_REGEX)`).
|
|
194
319
|
*/
|
|
195
|
-
const
|
|
320
|
+
export const CANVAS_IDENTIFIER_REGEX = /^[A-Za-z_][A-Za-z0-9_]{0,62}$/;
|
|
196
321
|
/**
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
* time rather than confusing-error time. The `IDENTIFIER_REGEX` is the
|
|
200
|
-
* authoritative shape gate.
|
|
322
|
+
* Courtesy guard against bare reserved words. Not exhaustive — the shape gate
|
|
323
|
+
* is authoritative; this just produces a friendlier error at register time.
|
|
201
324
|
*/
|
|
202
325
|
const RESERVED_IDENTIFIERS = new Set([
|
|
203
326
|
'select',
|
|
@@ -237,29 +360,25 @@ const RESERVED_IDENTIFIERS = new Set([
|
|
|
237
360
|
'with',
|
|
238
361
|
'recursive',
|
|
239
362
|
]);
|
|
240
|
-
/**
|
|
241
|
-
* Validate an identifier for use as a canvas-local table or column name.
|
|
242
|
-
* Throws `ValidationError` on rejection.
|
|
243
|
-
*/
|
|
363
|
+
/** Validate a canvas table or column name. Throws `ValidationError` on rejection. */
|
|
244
364
|
export function assertValidIdentifier(value, kind) {
|
|
245
365
|
if (typeof value !== 'string' || value.length === 0) {
|
|
246
366
|
throw validationError(`Canvas ${kind} name must be a non-empty string.`, {
|
|
247
|
-
reason:
|
|
367
|
+
reason: SQL_GATE_REASONS.identifierEmpty,
|
|
248
368
|
kind,
|
|
249
369
|
});
|
|
250
370
|
}
|
|
251
|
-
if (!
|
|
252
|
-
throw validationError(`Canvas ${kind} name "${value}" is invalid. Use letters, digits, and underscores; must start with a letter or underscore; max 63 chars.`, { reason:
|
|
371
|
+
if (!CANVAS_IDENTIFIER_REGEX.test(value)) {
|
|
372
|
+
throw validationError(`Canvas ${kind} name "${value}" is invalid. Use letters, digits, and underscores; must start with a letter or underscore; max 63 chars.`, { reason: SQL_GATE_REASONS.identifierShape, kind, value });
|
|
253
373
|
}
|
|
254
374
|
if (RESERVED_IDENTIFIERS.has(value.toLowerCase())) {
|
|
255
|
-
throw validationError(`Canvas ${kind} name "${value}" is a reserved SQL keyword. Choose another name.`, { reason:
|
|
375
|
+
throw validationError(`Canvas ${kind} name "${value}" is a reserved SQL keyword. Choose another name.`, { reason: SQL_GATE_REASONS.identifierReserved, kind, value });
|
|
256
376
|
}
|
|
257
377
|
}
|
|
258
378
|
/**
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
*
|
|
262
|
-
* only escapes; it does not validate shape.
|
|
379
|
+
* Double-quote-escape an identifier for SQL embedding. Validate via
|
|
380
|
+
* {@link assertValidIdentifier} first — this helper only escapes, it does not
|
|
381
|
+
* check shape.
|
|
263
382
|
*/
|
|
264
383
|
export function quoteIdentifier(value) {
|
|
265
384
|
return `"${value.replace(/"/g, '""')}"`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlGate.js","sourceRoot":"","sources":["../../../../src/services/canvas/core/sqlGate.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sqlGate.js","sourceRoot":"","sources":["../../../../src/services/canvas/core/sqlGate.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,7 @@ export { type AcquireResult, CanvasRegistry, type CanvasRegistryOptions, DEFAULT
|
|
|
15
15
|
export { createCanvasService } from './core/canvasFactory.js';
|
|
16
16
|
export { DataCanvas } from './core/DataCanvas.js';
|
|
17
17
|
export type { IDataCanvasProvider } from './core/IDataCanvasProvider.js';
|
|
18
|
-
export { ALLOWED_PLAN_OPERATORS, ALLOWED_STATEMENT_TYPES, assertReadOnlyQuery, assertValidIdentifier, collectDisallowedOperators, type DuckdbStatementType, quoteIdentifier, } from './core/sqlGate.js';
|
|
18
|
+
export { ALLOWED_PLAN_OPERATORS, ALLOWED_STATEMENT_TYPES, assertNoDeniedFunctions, assertReadOnlyQuery, assertValidIdentifier, CANVAS_IDENTIFIER_REGEX, collectDisallowedOperators, collectPlanViolations, DENIED_TABLE_FUNCTIONS, type DuckdbStatementType, quoteIdentifier, SQL_GATE_REASONS, type SqlGateReason, } from './core/sqlGate.js';
|
|
19
19
|
export { DuckdbProvider, type DuckdbProviderOptions, } from './providers/duckdb/DuckdbProvider.js';
|
|
20
20
|
export type { AcquireOptions, ColumnSchema, ColumnType, DescribeOptions, ExportFormat, ExportOptions, ExportResult, ExportTarget, QueryOptions, QueryResult, RegisterRows, RegisterTableOptions, RegisterTableResult, TableInfo, } from './types.js';
|
|
21
21
|
//# sourceMappingURL=index.d.ts.map
|