@dotsetlabs/tollgate 0.1.0

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.
Files changed (215) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +885 -0
  3. package/dist/analyzers/filesystem.d.ts +26 -0
  4. package/dist/analyzers/filesystem.d.ts.map +1 -0
  5. package/dist/analyzers/filesystem.js +284 -0
  6. package/dist/analyzers/filesystem.js.map +1 -0
  7. package/dist/analyzers/http.d.ts +90 -0
  8. package/dist/analyzers/http.d.ts.map +1 -0
  9. package/dist/analyzers/http.js +433 -0
  10. package/dist/analyzers/http.js.map +1 -0
  11. package/dist/analyzers/index.d.ts +101 -0
  12. package/dist/analyzers/index.d.ts.map +1 -0
  13. package/dist/analyzers/index.js +342 -0
  14. package/dist/analyzers/index.js.map +1 -0
  15. package/dist/analyzers/loader.d.ts +114 -0
  16. package/dist/analyzers/loader.d.ts.map +1 -0
  17. package/dist/analyzers/loader.js +184 -0
  18. package/dist/analyzers/loader.js.map +1 -0
  19. package/dist/analyzers/prompt-injection.d.ts +95 -0
  20. package/dist/analyzers/prompt-injection.d.ts.map +1 -0
  21. package/dist/analyzers/prompt-injection.js +725 -0
  22. package/dist/analyzers/prompt-injection.js.map +1 -0
  23. package/dist/analyzers/sdk.d.ts +230 -0
  24. package/dist/analyzers/sdk.d.ts.map +1 -0
  25. package/dist/analyzers/sdk.js +283 -0
  26. package/dist/analyzers/sdk.js.map +1 -0
  27. package/dist/analyzers/shell.d.ts +20 -0
  28. package/dist/analyzers/shell.d.ts.map +1 -0
  29. package/dist/analyzers/shell.js +297 -0
  30. package/dist/analyzers/shell.js.map +1 -0
  31. package/dist/analyzers/sql.d.ts +37 -0
  32. package/dist/analyzers/sql.d.ts.map +1 -0
  33. package/dist/analyzers/sql.js +455 -0
  34. package/dist/analyzers/sql.js.map +1 -0
  35. package/dist/analyzers/types.d.ts +117 -0
  36. package/dist/analyzers/types.d.ts.map +1 -0
  37. package/dist/analyzers/types.js +46 -0
  38. package/dist/analyzers/types.js.map +1 -0
  39. package/dist/approval/interactive.d.ts +72 -0
  40. package/dist/approval/interactive.d.ts.map +1 -0
  41. package/dist/approval/interactive.js +550 -0
  42. package/dist/approval/interactive.js.map +1 -0
  43. package/dist/approval/terminal.d.ts +59 -0
  44. package/dist/approval/terminal.d.ts.map +1 -0
  45. package/dist/approval/terminal.js +238 -0
  46. package/dist/approval/terminal.js.map +1 -0
  47. package/dist/approval/types.d.ts +66 -0
  48. package/dist/approval/types.d.ts.map +1 -0
  49. package/dist/approval/types.js +2 -0
  50. package/dist/approval/types.js.map +1 -0
  51. package/dist/audit/exporter.d.ts +138 -0
  52. package/dist/audit/exporter.d.ts.map +1 -0
  53. package/dist/audit/exporter.js +366 -0
  54. package/dist/audit/exporter.js.map +1 -0
  55. package/dist/audit/logger.d.ts +156 -0
  56. package/dist/audit/logger.d.ts.map +1 -0
  57. package/dist/audit/logger.js +406 -0
  58. package/dist/audit/logger.js.map +1 -0
  59. package/dist/audit/redaction.d.ts +110 -0
  60. package/dist/audit/redaction.d.ts.map +1 -0
  61. package/dist/audit/redaction.js +307 -0
  62. package/dist/audit/redaction.js.map +1 -0
  63. package/dist/audit/schema.d.ts +76 -0
  64. package/dist/audit/schema.d.ts.map +1 -0
  65. package/dist/audit/schema.js +122 -0
  66. package/dist/audit/schema.js.map +1 -0
  67. package/dist/cli/commands/doctor.d.ts +34 -0
  68. package/dist/cli/commands/doctor.d.ts.map +1 -0
  69. package/dist/cli/commands/doctor.js +431 -0
  70. package/dist/cli/commands/doctor.js.map +1 -0
  71. package/dist/cli/commands/export.d.ts +18 -0
  72. package/dist/cli/commands/export.d.ts.map +1 -0
  73. package/dist/cli/commands/export.js +63 -0
  74. package/dist/cli/commands/export.js.map +1 -0
  75. package/dist/cli/commands/init.d.ts +12 -0
  76. package/dist/cli/commands/init.d.ts.map +1 -0
  77. package/dist/cli/commands/init.js +102 -0
  78. package/dist/cli/commands/init.js.map +1 -0
  79. package/dist/cli/commands/logs.d.ts +11 -0
  80. package/dist/cli/commands/logs.d.ts.map +1 -0
  81. package/dist/cli/commands/logs.js +60 -0
  82. package/dist/cli/commands/logs.js.map +1 -0
  83. package/dist/cli/commands/scan.d.ts +29 -0
  84. package/dist/cli/commands/scan.d.ts.map +1 -0
  85. package/dist/cli/commands/scan.js +251 -0
  86. package/dist/cli/commands/scan.js.map +1 -0
  87. package/dist/cli/commands/serve.d.ts +26 -0
  88. package/dist/cli/commands/serve.d.ts.map +1 -0
  89. package/dist/cli/commands/serve.js +424 -0
  90. package/dist/cli/commands/serve.js.map +1 -0
  91. package/dist/cli/commands/start.d.ts +20 -0
  92. package/dist/cli/commands/start.d.ts.map +1 -0
  93. package/dist/cli/commands/start.js +82 -0
  94. package/dist/cli/commands/start.js.map +1 -0
  95. package/dist/cli/commands/stats.d.ts +10 -0
  96. package/dist/cli/commands/stats.d.ts.map +1 -0
  97. package/dist/cli/commands/stats.js +42 -0
  98. package/dist/cli/commands/stats.js.map +1 -0
  99. package/dist/cli/commands/templates.d.ts +26 -0
  100. package/dist/cli/commands/templates.d.ts.map +1 -0
  101. package/dist/cli/commands/templates.js +221 -0
  102. package/dist/cli/commands/templates.js.map +1 -0
  103. package/dist/cli/commands/validate.d.ts +12 -0
  104. package/dist/cli/commands/validate.d.ts.map +1 -0
  105. package/dist/cli/commands/validate.js +107 -0
  106. package/dist/cli/commands/validate.js.map +1 -0
  107. package/dist/cli/commands/wrap.d.ts +19 -0
  108. package/dist/cli/commands/wrap.d.ts.map +1 -0
  109. package/dist/cli/commands/wrap.js +59 -0
  110. package/dist/cli/commands/wrap.js.map +1 -0
  111. package/dist/cli/index.d.ts +17 -0
  112. package/dist/cli/index.d.ts.map +1 -0
  113. package/dist/cli/index.js +202 -0
  114. package/dist/cli/index.js.map +1 -0
  115. package/dist/cli/ui.d.ts +139 -0
  116. package/dist/cli/ui.d.ts.map +1 -0
  117. package/dist/cli/ui.js +271 -0
  118. package/dist/cli/ui.js.map +1 -0
  119. package/dist/constants.d.ts +33 -0
  120. package/dist/constants.d.ts.map +1 -0
  121. package/dist/constants.js +54 -0
  122. package/dist/constants.js.map +1 -0
  123. package/dist/errors.d.ts +28 -0
  124. package/dist/errors.d.ts.map +1 -0
  125. package/dist/errors.js +37 -0
  126. package/dist/errors.js.map +1 -0
  127. package/dist/index.d.ts +49 -0
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +82 -0
  130. package/dist/index.js.map +1 -0
  131. package/dist/orchestrator/index.d.ts +11 -0
  132. package/dist/orchestrator/index.d.ts.map +1 -0
  133. package/dist/orchestrator/index.js +10 -0
  134. package/dist/orchestrator/index.js.map +1 -0
  135. package/dist/orchestrator/manager.d.ts +127 -0
  136. package/dist/orchestrator/manager.d.ts.map +1 -0
  137. package/dist/orchestrator/manager.js +498 -0
  138. package/dist/orchestrator/manager.js.map +1 -0
  139. package/dist/orchestrator/types.d.ts +141 -0
  140. package/dist/orchestrator/types.d.ts.map +1 -0
  141. package/dist/orchestrator/types.js +9 -0
  142. package/dist/orchestrator/types.js.map +1 -0
  143. package/dist/policy/engine.d.ts +55 -0
  144. package/dist/policy/engine.d.ts.map +1 -0
  145. package/dist/policy/engine.js +288 -0
  146. package/dist/policy/engine.js.map +1 -0
  147. package/dist/policy/natural-language.d.ts +141 -0
  148. package/dist/policy/natural-language.d.ts.map +1 -0
  149. package/dist/policy/natural-language.js +552 -0
  150. package/dist/policy/natural-language.js.map +1 -0
  151. package/dist/policy/parser.d.ts +141 -0
  152. package/dist/policy/parser.d.ts.map +1 -0
  153. package/dist/policy/parser.js +314 -0
  154. package/dist/policy/parser.js.map +1 -0
  155. package/dist/policy/types.d.ts +428 -0
  156. package/dist/policy/types.d.ts.map +1 -0
  157. package/dist/policy/types.js +32 -0
  158. package/dist/policy/types.js.map +1 -0
  159. package/dist/policy/validator.d.ts +72 -0
  160. package/dist/policy/validator.d.ts.map +1 -0
  161. package/dist/policy/validator.js +453 -0
  162. package/dist/policy/validator.js.map +1 -0
  163. package/dist/proxy/bridge.d.ts +84 -0
  164. package/dist/proxy/bridge.d.ts.map +1 -0
  165. package/dist/proxy/bridge.js +217 -0
  166. package/dist/proxy/bridge.js.map +1 -0
  167. package/dist/proxy/client.d.ts +130 -0
  168. package/dist/proxy/client.d.ts.map +1 -0
  169. package/dist/proxy/client.js +290 -0
  170. package/dist/proxy/client.js.map +1 -0
  171. package/dist/proxy/server.d.ts +111 -0
  172. package/dist/proxy/server.d.ts.map +1 -0
  173. package/dist/proxy/server.js +444 -0
  174. package/dist/proxy/server.js.map +1 -0
  175. package/dist/scanner.d.ts +91 -0
  176. package/dist/scanner.d.ts.map +1 -0
  177. package/dist/scanner.js +373 -0
  178. package/dist/scanner.js.map +1 -0
  179. package/dist/session/index.d.ts +32 -0
  180. package/dist/session/index.d.ts.map +1 -0
  181. package/dist/session/index.js +31 -0
  182. package/dist/session/index.js.map +1 -0
  183. package/dist/session/manager.d.ts +166 -0
  184. package/dist/session/manager.d.ts.map +1 -0
  185. package/dist/session/manager.js +454 -0
  186. package/dist/session/manager.js.map +1 -0
  187. package/dist/session/sqlite-store.d.ts +54 -0
  188. package/dist/session/sqlite-store.d.ts.map +1 -0
  189. package/dist/session/sqlite-store.js +209 -0
  190. package/dist/session/sqlite-store.js.map +1 -0
  191. package/dist/session/types.d.ts +179 -0
  192. package/dist/session/types.d.ts.map +1 -0
  193. package/dist/session/types.js +38 -0
  194. package/dist/session/types.js.map +1 -0
  195. package/dist/templates.d.ts +64 -0
  196. package/dist/templates.d.ts.map +1 -0
  197. package/dist/templates.js +451 -0
  198. package/dist/templates.js.map +1 -0
  199. package/dist/utils/config.d.ts +57 -0
  200. package/dist/utils/config.d.ts.map +1 -0
  201. package/dist/utils/config.js +104 -0
  202. package/dist/utils/config.js.map +1 -0
  203. package/dist/utils/errors.d.ts +18 -0
  204. package/dist/utils/errors.d.ts.map +1 -0
  205. package/dist/utils/errors.js +35 -0
  206. package/dist/utils/errors.js.map +1 -0
  207. package/dist/utils/logger.d.ts +144 -0
  208. package/dist/utils/logger.d.ts.map +1 -0
  209. package/dist/utils/logger.js +300 -0
  210. package/dist/utils/logger.js.map +1 -0
  211. package/dist/wizard.d.ts +68 -0
  212. package/dist/wizard.d.ts.map +1 -0
  213. package/dist/wizard.js +395 -0
  214. package/dist/wizard.js.map +1 -0
  215. package/package.json +99 -0
@@ -0,0 +1,455 @@
1
+ import NodeSqlParser from 'node-sql-parser';
2
+ const { Parser } = NodeSqlParser;
3
+ /**
4
+ * SQL Statement Analyzer
5
+ *
6
+ * Classifies SQL statements by risk level:
7
+ * - read: SELECT statements
8
+ * - write: INSERT statements
9
+ * - write/destructive: UPDATE/DELETE with WHERE clause
10
+ * - dangerous: UPDATE/DELETE without WHERE, DROP, TRUNCATE, ALTER
11
+ */
12
+ export class SqlAnalyzer {
13
+ name = 'sql';
14
+ parser;
15
+ constructor() {
16
+ this.parser = new Parser();
17
+ }
18
+ analyze(sql, _context) {
19
+ // First, check for obviously dangerous patterns via regex
20
+ // (catches cases parser might miss or malformed SQL)
21
+ const dangerousPatterns = this.checkDangerousPatterns(sql);
22
+ if (dangerousPatterns) {
23
+ return dangerousPatterns;
24
+ }
25
+ try {
26
+ const ast = this.parser.astify(sql, { database: 'PostgreSQL' });
27
+ const statements = Array.isArray(ast) ? ast : [ast];
28
+ // Analyze all statements and return the highest risk
29
+ let highestRisk = {
30
+ risk: 'safe',
31
+ reason: 'Empty or no-op statement',
32
+ };
33
+ for (const stmt of statements) {
34
+ const result = this.analyzeStatement(stmt);
35
+ if (this.isHigherRisk(result.risk, highestRisk.risk)) {
36
+ highestRisk = result;
37
+ }
38
+ }
39
+ return highestRisk;
40
+ }
41
+ catch (error) {
42
+ // If we can't parse it, be conservative
43
+ // Sanitize error messages to avoid leaking schema information
44
+ const sanitizedReason = error instanceof Error
45
+ ? 'SQL parse error (details hidden for security)'
46
+ : 'unknown error';
47
+ return {
48
+ risk: 'dangerous',
49
+ reason: `Unable to parse SQL: ${sanitizedReason}`,
50
+ metadata: { parseError: true },
51
+ };
52
+ }
53
+ }
54
+ analyzeStatement(stmt) {
55
+ const statement = stmt;
56
+ const type = statement.type?.toLowerCase();
57
+ switch (type) {
58
+ case 'select':
59
+ return this.analyzeSelect(statement);
60
+ case 'insert':
61
+ return {
62
+ risk: 'write',
63
+ reason: 'INSERT statement adds new data',
64
+ metadata: { statementType: 'insert' },
65
+ };
66
+ case 'update':
67
+ return this.analyzeUpdate(statement);
68
+ case 'delete':
69
+ return this.analyzeDelete(statement);
70
+ case 'drop':
71
+ return {
72
+ risk: 'dangerous',
73
+ reason: `DROP statement permanently removes database objects`,
74
+ triggers: ['DROP'],
75
+ metadata: { statementType: 'drop' },
76
+ };
77
+ case 'truncate':
78
+ return {
79
+ risk: 'dangerous',
80
+ reason: 'TRUNCATE removes all data from table',
81
+ triggers: ['TRUNCATE'],
82
+ metadata: { statementType: 'truncate' },
83
+ };
84
+ case 'alter':
85
+ return {
86
+ risk: 'destructive',
87
+ reason: 'ALTER modifies table structure',
88
+ triggers: ['ALTER'],
89
+ metadata: { statementType: 'alter' },
90
+ };
91
+ case 'create':
92
+ return {
93
+ risk: 'write',
94
+ reason: 'CREATE adds new database objects',
95
+ metadata: { statementType: 'create' },
96
+ };
97
+ case 'grant':
98
+ case 'revoke':
99
+ return {
100
+ risk: 'dangerous',
101
+ reason: `${type.toUpperCase()} modifies database permissions`,
102
+ triggers: [type.toUpperCase()],
103
+ metadata: { statementType: type },
104
+ };
105
+ default:
106
+ return {
107
+ risk: 'write',
108
+ reason: `Unknown statement type: ${type}`,
109
+ metadata: { statementType: type },
110
+ };
111
+ }
112
+ }
113
+ analyzeSelect(stmt) {
114
+ // Check for SELECT INTO (creates new table)
115
+ const into = stmt.into;
116
+ if (into && into.expr) {
117
+ return {
118
+ risk: 'write',
119
+ reason: 'SELECT INTO creates a new table',
120
+ metadata: { statementType: 'select_into' },
121
+ };
122
+ }
123
+ // Check for subqueries that might modify data (rare but possible)
124
+ // For now, treat SELECT as read-only
125
+ return {
126
+ risk: 'read',
127
+ reason: 'SELECT statement reads data',
128
+ metadata: { statementType: 'select' },
129
+ };
130
+ }
131
+ analyzeUpdate(stmt) {
132
+ const where = stmt.where;
133
+ if (!where) {
134
+ return {
135
+ risk: 'dangerous',
136
+ reason: 'UPDATE without WHERE clause affects ALL rows',
137
+ triggers: ['UPDATE without WHERE'],
138
+ metadata: { statementType: 'update', hasWhere: false },
139
+ };
140
+ }
141
+ // Check for always-true conditions like WHERE 1=1
142
+ if (this.isAlwaysTrueCondition(where)) {
143
+ return {
144
+ risk: 'dangerous',
145
+ reason: 'UPDATE with always-true condition affects ALL rows',
146
+ triggers: ['UPDATE WHERE 1=1'],
147
+ metadata: { statementType: 'update', hasWhere: true, alwaysTrue: true },
148
+ };
149
+ }
150
+ return {
151
+ risk: 'write',
152
+ reason: 'UPDATE statement modifies existing data',
153
+ metadata: { statementType: 'update', hasWhere: true },
154
+ };
155
+ }
156
+ analyzeDelete(stmt) {
157
+ const where = stmt.where;
158
+ if (!where) {
159
+ return {
160
+ risk: 'dangerous',
161
+ reason: 'DELETE without WHERE clause removes ALL rows',
162
+ triggers: ['DELETE without WHERE'],
163
+ metadata: { statementType: 'delete', hasWhere: false },
164
+ };
165
+ }
166
+ // Check for always-true conditions
167
+ if (this.isAlwaysTrueCondition(where)) {
168
+ return {
169
+ risk: 'dangerous',
170
+ reason: 'DELETE with always-true condition removes ALL rows',
171
+ triggers: ['DELETE WHERE 1=1'],
172
+ metadata: { statementType: 'delete', hasWhere: true, alwaysTrue: true },
173
+ };
174
+ }
175
+ return {
176
+ risk: 'destructive',
177
+ reason: 'DELETE statement removes data',
178
+ metadata: { statementType: 'delete', hasWhere: true },
179
+ };
180
+ }
181
+ isAlwaysTrueCondition(where) {
182
+ const condition = where;
183
+ // Check for 1=1, true, etc.
184
+ if (condition.type === 'binary_expr') {
185
+ const left = condition.left;
186
+ const right = condition.right;
187
+ const operator = condition.operator;
188
+ // 1=1, 'a'='a', etc.
189
+ if (operator === '=' && left.type === 'number' && right.type === 'number') {
190
+ if (left.value === right.value)
191
+ return true;
192
+ }
193
+ // TRUE
194
+ if (left.type === 'bool' && left.value === true)
195
+ return true;
196
+ }
197
+ return false;
198
+ }
199
+ checkDangerousPatterns(sql) {
200
+ // Normalize SQL by removing comments for more accurate pattern detection
201
+ const normalizedSql = this.removeComments(sql);
202
+ // Recursive CTEs can cause infinite loops / DoS
203
+ if (/WITH\s+RECURSIVE/i.test(normalizedSql)) {
204
+ return {
205
+ risk: 'dangerous',
206
+ reason: 'Recursive CTE detected - can cause infinite loops or resource exhaustion',
207
+ triggers: ['WITH RECURSIVE'],
208
+ metadata: { dosRisk: 'recursive_cte' },
209
+ };
210
+ }
211
+ // DoS-prone functions that can cause resource exhaustion
212
+ const dosPatterns = this.checkDosFunctions(normalizedSql);
213
+ if (dosPatterns) {
214
+ return dosPatterns;
215
+ }
216
+ // Multiple statements (potential SQL injection)
217
+ // Count semicolons outside of string literals
218
+ const semicolonCount = this.countSemicolonsOutsideStrings(sql);
219
+ if (semicolonCount > 3) {
220
+ return {
221
+ risk: 'dangerous',
222
+ reason: 'Multiple SQL statements detected (potential injection)',
223
+ triggers: ['multiple statements'],
224
+ };
225
+ }
226
+ // Comment injection patterns
227
+ if (sql.includes('--') || sql.includes('/*')) {
228
+ // Check if it's suspicious (comment after quote)
229
+ // Use bounded character class to prevent ReDoS
230
+ if (/['"][^'"]{0,1000}--/.test(sql) || /['"][^'"]{0,1000}\/\*/.test(sql)) {
231
+ return {
232
+ risk: 'dangerous',
233
+ reason: 'Potential SQL injection pattern detected (comment after string)',
234
+ triggers: ['comment injection pattern'],
235
+ };
236
+ }
237
+ }
238
+ // UNION-based injection (check normalized SQL without comments)
239
+ if (/UNION\s+(ALL\s+)?SELECT/i.test(normalizedSql)) {
240
+ return {
241
+ risk: 'dangerous',
242
+ reason: 'UNION SELECT pattern detected (potential injection)',
243
+ triggers: ['UNION SELECT'],
244
+ };
245
+ }
246
+ // System commands
247
+ if (/xp_cmdshell|exec\s+master|LOAD_FILE|INTO\s+OUTFILE|INTO\s+DUMPFILE/i.test(normalizedSql)) {
248
+ return {
249
+ risk: 'dangerous',
250
+ reason: 'System command execution pattern detected',
251
+ triggers: ['system command'],
252
+ };
253
+ }
254
+ // Unbounded CROSS JOIN without LIMIT (cartesian product DoS)
255
+ // Use normalized SQL to catch comment-based bypass attempts like CROSS/**/JOIN
256
+ if (/CROSS\s+JOIN/i.test(normalizedSql) && !/LIMIT\s+\d+/i.test(normalizedSql)) {
257
+ return {
258
+ risk: 'destructive',
259
+ reason: 'CROSS JOIN without LIMIT can cause cartesian product explosion',
260
+ triggers: ['CROSS JOIN without LIMIT'],
261
+ metadata: { dosRisk: 'unbounded_cross_join' },
262
+ };
263
+ }
264
+ return null;
265
+ }
266
+ /**
267
+ * Remove SQL comments for pattern matching
268
+ * Handles both -- line comments and /* block comments
269
+ */
270
+ removeComments(sql) {
271
+ let result = '';
272
+ let i = 0;
273
+ let inString = false;
274
+ let stringChar = '';
275
+ while (i < sql.length) {
276
+ // Track string literals to avoid removing content inside strings
277
+ if (!inString && (sql[i] === "'" || sql[i] === '"')) {
278
+ inString = true;
279
+ stringChar = sql[i];
280
+ result += sql[i];
281
+ i++;
282
+ continue;
283
+ }
284
+ if (inString) {
285
+ // Check for escape sequence or end of string
286
+ if (sql[i] === stringChar) {
287
+ // Check for escaped quote ('' or "")
288
+ if (i + 1 < sql.length && sql[i + 1] === stringChar) {
289
+ result += sql[i] + sql[i + 1];
290
+ i += 2;
291
+ continue;
292
+ }
293
+ inString = false;
294
+ }
295
+ result += sql[i];
296
+ i++;
297
+ continue;
298
+ }
299
+ // Block comment
300
+ if (sql[i] === '/' && i + 1 < sql.length && sql[i + 1] === '*') {
301
+ // Skip until */
302
+ i += 2;
303
+ while (i < sql.length - 1 && !(sql[i] === '*' && sql[i + 1] === '/')) {
304
+ i++;
305
+ }
306
+ i += 2; // Skip */
307
+ result += ' '; // Replace comment with space to preserve token separation
308
+ continue;
309
+ }
310
+ // Line comment
311
+ if (sql[i] === '-' && i + 1 < sql.length && sql[i + 1] === '-') {
312
+ // Skip until end of line
313
+ while (i < sql.length && sql[i] !== '\n') {
314
+ i++;
315
+ }
316
+ result += ' '; // Replace comment with space
317
+ continue;
318
+ }
319
+ result += sql[i];
320
+ i++;
321
+ }
322
+ return result;
323
+ }
324
+ /**
325
+ * Count semicolons that are outside of string literals
326
+ */
327
+ countSemicolonsOutsideStrings(sql) {
328
+ let count = 0;
329
+ let inString = false;
330
+ let stringChar = '';
331
+ for (let i = 0; i < sql.length; i++) {
332
+ const char = sql[i];
333
+ // Track string literals
334
+ if (!inString && (char === "'" || char === '"')) {
335
+ inString = true;
336
+ stringChar = char;
337
+ continue;
338
+ }
339
+ if (inString) {
340
+ if (char === stringChar) {
341
+ // Check for escaped quote ('' or "")
342
+ if (i + 1 < sql.length && sql[i + 1] === stringChar) {
343
+ i++; // Skip the escaped quote
344
+ continue;
345
+ }
346
+ inString = false;
347
+ }
348
+ continue;
349
+ }
350
+ // Count semicolons outside strings
351
+ if (char === ';') {
352
+ count++;
353
+ }
354
+ }
355
+ return count;
356
+ }
357
+ /**
358
+ * Check for functions that can cause DoS / resource exhaustion
359
+ */
360
+ checkDosFunctions(sql) {
361
+ // PostgreSQL sleep function - obvious DoS
362
+ if (/pg_sleep\s*\(/i.test(sql)) {
363
+ return {
364
+ risk: 'dangerous',
365
+ reason: 'pg_sleep() can cause denial of service',
366
+ triggers: ['pg_sleep()'],
367
+ metadata: { dosRisk: 'sleep_function' },
368
+ };
369
+ }
370
+ // MySQL sleep
371
+ if (/\bsleep\s*\(/i.test(sql) && !/pg_sleep/i.test(sql)) {
372
+ return {
373
+ risk: 'dangerous',
374
+ reason: 'SLEEP() can cause denial of service',
375
+ triggers: ['SLEEP()'],
376
+ metadata: { dosRisk: 'sleep_function' },
377
+ };
378
+ }
379
+ // PostgreSQL benchmark/waitfor functions
380
+ if (/waitfor\s+delay/i.test(sql)) {
381
+ return {
382
+ risk: 'dangerous',
383
+ reason: 'WAITFOR DELAY can cause denial of service',
384
+ triggers: ['WAITFOR DELAY'],
385
+ metadata: { dosRisk: 'delay_function' },
386
+ };
387
+ }
388
+ // generate_series with large ranges can exhaust memory
389
+ // Use bounded whitespace to prevent ReDoS
390
+ const genSeriesMatch = sql.match(/generate_series\s{0,10}\(\s{0,10}(\d+)\s{0,10},\s{0,10}(\d+)/i);
391
+ if (genSeriesMatch && genSeriesMatch[1] && genSeriesMatch[2]) {
392
+ const start = parseInt(genSeriesMatch[1], 10);
393
+ const end = parseInt(genSeriesMatch[2], 10);
394
+ const range = Math.abs(end - start);
395
+ // Flag if generating more than 1 million rows
396
+ if (range > 1000000) {
397
+ return {
398
+ risk: 'dangerous',
399
+ reason: `generate_series() with ${range.toLocaleString()} rows can exhaust memory`,
400
+ triggers: ['generate_series(large range)'],
401
+ metadata: { dosRisk: 'large_generate_series', rowCount: range },
402
+ };
403
+ }
404
+ else if (range > 100000) {
405
+ return {
406
+ risk: 'destructive',
407
+ reason: `generate_series() with ${range.toLocaleString()} rows may impact performance`,
408
+ triggers: ['generate_series(medium range)'],
409
+ metadata: { dosRisk: 'medium_generate_series', rowCount: range },
410
+ };
411
+ }
412
+ }
413
+ // repeat() with large counts
414
+ const repeatMatch = sql.match(/repeat\s*\([^,]+,\s*(\d+)\s*\)/i);
415
+ if (repeatMatch && repeatMatch[1]) {
416
+ const count = parseInt(repeatMatch[1], 10);
417
+ if (count > 1000000) {
418
+ return {
419
+ risk: 'dangerous',
420
+ reason: `repeat() with count ${count.toLocaleString()} can exhaust memory`,
421
+ triggers: ['repeat(large count)'],
422
+ metadata: { dosRisk: 'large_repeat', count },
423
+ };
424
+ }
425
+ }
426
+ // MD5/SHA hash loops (common DoS pattern)
427
+ if (/md5\s*\(\s*md5\s*\(/i.test(sql) || /sha\d*\s*\(\s*sha\d*\s*\(/i.test(sql)) {
428
+ return {
429
+ risk: 'destructive',
430
+ reason: 'Nested hash functions may indicate DoS attempt',
431
+ triggers: ['nested hash functions'],
432
+ metadata: { dosRisk: 'nested_hash' },
433
+ };
434
+ }
435
+ // Large LIMIT values that could fetch too much data
436
+ const limitMatch = sql.match(/LIMIT\s+(\d+)/i);
437
+ if (limitMatch && limitMatch[1]) {
438
+ const limit = parseInt(limitMatch[1], 10);
439
+ if (limit > 10000000) {
440
+ return {
441
+ risk: 'destructive',
442
+ reason: `LIMIT ${limit.toLocaleString()} may transfer excessive data`,
443
+ triggers: ['LIMIT(excessive)'],
444
+ metadata: { dosRisk: 'large_limit', limit },
445
+ };
446
+ }
447
+ }
448
+ return null;
449
+ }
450
+ isHigherRisk(a, b) {
451
+ const riskOrder = ['safe', 'read', 'write', 'destructive', 'dangerous'];
452
+ return riskOrder.indexOf(a) > riskOrder.indexOf(b);
453
+ }
454
+ }
455
+ //# sourceMappingURL=sql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.js","sourceRoot":"","sources":["../../src/analyzers/sql.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Content Analyzer Type Definitions
3
+ *
4
+ * This module defines the types for Tollgate's smart content analysis system.
5
+ * Analyzers examine tool arguments to determine risk levels, enabling
6
+ * context-aware policy decisions.
7
+ *
8
+ * Built-in analyzers:
9
+ * - **SQL**: Parses SQL queries to detect reads, writes, and destructive operations
10
+ * - **Filesystem**: Analyzes file paths for sensitive or dangerous locations
11
+ * - **Shell**: Detects dangerous shell command patterns
12
+ * - **HTTP**: Prevents SSRF attacks by analyzing URLs, methods, and headers
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import type { ContentAnalyzer, AnalysisResult, RiskLevel } from './types.js';
17
+ *
18
+ * class CustomAnalyzer implements ContentAnalyzer {
19
+ * readonly name = 'custom';
20
+ *
21
+ * analyze(content: string): AnalysisResult {
22
+ * return {
23
+ * risk: 'safe',
24
+ * reason: 'Content passed custom validation'
25
+ * };
26
+ * }
27
+ * }
28
+ * ```
29
+ *
30
+ * @module analyzers/types
31
+ */
32
+ /**
33
+ * Risk levels for analyzed content.
34
+ *
35
+ * Risk levels form a hierarchy from lowest to highest risk:
36
+ * 1. `safe` - No risk, proceed automatically
37
+ * 2. `read` - Read-only operation, typically safe
38
+ * 3. `write` - Modifies data, may need approval
39
+ * 4. `destructive` - Removes/deletes data, should prompt
40
+ * 5. `dangerous` - High risk, should deny or require explicit approval
41
+ */
42
+ export type RiskLevel = 'safe' | 'read' | 'write' | 'destructive' | 'dangerous';
43
+ /**
44
+ * Result of content analysis.
45
+ *
46
+ * Contains the risk assessment along with supporting information
47
+ * for audit logging and user display.
48
+ */
49
+ export interface AnalysisResult {
50
+ /** The determined risk level */
51
+ risk: RiskLevel;
52
+ /** Human-readable reason for the classification */
53
+ reason: string;
54
+ /** Specific patterns or elements that triggered the classification */
55
+ triggers?: string[];
56
+ /** Additional metadata about the analysis */
57
+ metadata?: Record<string, unknown>;
58
+ }
59
+ /**
60
+ * Interface for content analyzers.
61
+ *
62
+ * All analyzers must implement this interface. Analyzers are stateless
63
+ * and should be safe to call concurrently.
64
+ */
65
+ export interface ContentAnalyzer {
66
+ /** Unique identifier for this analyzer */
67
+ readonly name: string;
68
+ /** Analyze content and return risk assessment */
69
+ analyze(content: string, context?: AnalyzerContext): AnalysisResult;
70
+ }
71
+ /**
72
+ * Context provided to analyzers for more informed decisions.
73
+ *
74
+ * Provides additional information about the request that may
75
+ * influence the risk assessment.
76
+ */
77
+ export interface AnalyzerContext {
78
+ /** The tool being called */
79
+ tool?: string;
80
+ /** The server name */
81
+ server?: string;
82
+ /** Additional arguments that might inform analysis */
83
+ args?: Record<string, unknown>;
84
+ }
85
+ /**
86
+ * Mapping from risk levels to policy actions.
87
+ *
88
+ * Used in smart policies to define how each risk level should be handled.
89
+ * Unspecified levels fall back to DEFAULT_RISK_MAPPING.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * const strictMapping: RiskMapping = {
94
+ * safe: 'allow',
95
+ * read: 'allow',
96
+ * write: 'prompt',
97
+ * destructive: 'deny', // Stricter than default
98
+ * dangerous: 'deny'
99
+ * };
100
+ * ```
101
+ */
102
+ export interface RiskMapping {
103
+ safe?: 'allow' | 'prompt' | 'deny';
104
+ read?: 'allow' | 'prompt' | 'deny';
105
+ write?: 'allow' | 'prompt' | 'deny';
106
+ destructive?: 'allow' | 'prompt' | 'deny';
107
+ dangerous?: 'allow' | 'prompt' | 'deny';
108
+ }
109
+ /**
110
+ * Default risk mapping with sensible security defaults.
111
+ *
112
+ * - Safe and read operations are allowed automatically
113
+ * - Write and destructive operations require user approval
114
+ * - Dangerous operations are denied by default
115
+ */
116
+ export declare const DEFAULT_RISK_MAPPING: Required<RiskMapping>;
117
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/analyzers/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAMH;;;;;;;;;GASG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,GAAG,WAAW,CAAC;AAEhF;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,gCAAgC;IAChC,IAAI,EAAE,SAAS,CAAC;IAEhB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IAEf,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAMD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,iDAAiD;IACjD,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,cAAc,CAAC;CACrE;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,4BAA4B;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACnC,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACnC,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC1C,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CACzC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,WAAW,CAMtD,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Content Analyzer Type Definitions
3
+ *
4
+ * This module defines the types for Tollgate's smart content analysis system.
5
+ * Analyzers examine tool arguments to determine risk levels, enabling
6
+ * context-aware policy decisions.
7
+ *
8
+ * Built-in analyzers:
9
+ * - **SQL**: Parses SQL queries to detect reads, writes, and destructive operations
10
+ * - **Filesystem**: Analyzes file paths for sensitive or dangerous locations
11
+ * - **Shell**: Detects dangerous shell command patterns
12
+ * - **HTTP**: Prevents SSRF attacks by analyzing URLs, methods, and headers
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import type { ContentAnalyzer, AnalysisResult, RiskLevel } from './types.js';
17
+ *
18
+ * class CustomAnalyzer implements ContentAnalyzer {
19
+ * readonly name = 'custom';
20
+ *
21
+ * analyze(content: string): AnalysisResult {
22
+ * return {
23
+ * risk: 'safe',
24
+ * reason: 'Content passed custom validation'
25
+ * };
26
+ * }
27
+ * }
28
+ * ```
29
+ *
30
+ * @module analyzers/types
31
+ */
32
+ /**
33
+ * Default risk mapping with sensible security defaults.
34
+ *
35
+ * - Safe and read operations are allowed automatically
36
+ * - Write and destructive operations require user approval
37
+ * - Dangerous operations are denied by default
38
+ */
39
+ export const DEFAULT_RISK_MAPPING = {
40
+ safe: 'allow',
41
+ read: 'allow',
42
+ write: 'prompt',
43
+ destructive: 'prompt',
44
+ dangerous: 'deny',
45
+ };
46
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/analyzers/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAsGH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA0B;IACzD,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,QAAQ;IACf,WAAW,EAAE,QAAQ;IACrB,SAAS,EAAE,MAAM;CAClB,CAAC"}