{"record":{"id":"e06ea3b051e49a07","repo":"nocobase/nocobase","slug":"sql-statements-contain-dangerous-keywords","errorCode":null,"errorMessage":"SQL statements contain dangerous keywords","messagePattern":"SQL statements contain dangerous keywords","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/plugins/@nocobase/plugin-collection-sql/src/server/utils.ts","lineNumber":48,"sourceCode":"    'pg_stat_activity',\n    'information_schema',\n\n    // MySQL\n    'LOAD_FILE',\n    'BENCHMARK',\n    '@@global.',\n    '@@session.',\n\n    // SQLite\n    'sqlite3_load_extension',\n    'load_extension',\n  ];\n  sql = sql.trim().split(';').shift() || '';\n  if (!/^select/i.test(sql) && !/^with([\\s\\S]+)select([\\s\\S]+)/i.test(sql)) {\n    throw new Error('Only supports SELECT statements or WITH clauses');\n  }\n  if (dangerKeywords.some((keyword) => sql.toLowerCase().includes(keyword.toLowerCase()))) {\n    throw new Error('SQL statements contain dangerous keywords');\n  }\n};\n","sourceCodeStart":30,"sourceCodeEnd":51,"githubUrl":"https://github.com/nocobase/nocobase/blob/fa42722fefe44265490dff2c27d79e2882bce4fa/packages/plugins/@nocobase/plugin-collection-sql/src/server/utils.ts#L30-L51","documentation":"After confirming the query is a SELECT/WITH, checkSQL scans it case-insensitively for dangerous keywords (e.g. sqlite3_load_extension, load_extension, and other write/DDL keywords in the dangerKeywords list). Substring matching means any occurrence — even inside a string literal, column name, or comment — triggers this error.","triggerScenarios":"A SELECT query whose text contains any danger keyword, e.g. `SELECT * FROM load_extension_log`, a WHERE clause string like `name = 'delete_me'`, or keywords such as INSERT/UPDATE/DROP appearing in aliases or comments.","commonSituations":"Table or column names coincidentally contain a banned word; query embeds literal strings mentioning those words; developer tries to sneak a write via a CTE.","solutions":["Remove or rename the offending keyword occurrence (alias the column/table, reword string literals).","Check the dangerKeywords list in src/server/utils.ts to identify which keyword matched.","If a legitimate identifier collides, rename the column/table or use a quoted alias that avoids the banned substring.","Perform the write elsewhere — this validator is intentionally strict."],"exampleFix":"// before\nconst sql = \"SELECT * FROM insertions_log\"; // contains 'insert'\n// after\nconst sql = \"SELECT * FROM event_log WHERE kind = 'insertion'\"; // avoid banned substrings","handlingStrategy":"validation","validationCode":"// scan for the same banned substrings before submitting\nconst DANGEROUS = ['insert','update','delete','drop','alter','create','load_extension','sqlite3_load_extension'];\nconst hits = DANGEROUS.filter((k) => userSql.toLowerCase().includes(k));\nif (hits.length) console.warn('rename offending identifiers/literals:', hits);","typeGuard":null,"tryCatchPattern":"try {\n  await sqlCollectionRepo.create({ values: { sql: userSql } });\n} catch (e) {\n  if (e.message === 'SQL statements contain dangerous keywords') {\n    // locate and remove/rename the keyword occurrence (aliases, string literals, comments)\n  }\n}","preventionTips":["Avoid table/column names or string literals containing banned substrings.","Read the dangerKeywords array in plugin-collection-sql/src/server/utils.ts to know the blocklist.","Assume substring matching: even inside quotes, keywords count."],"tags":["sql","security","validation","dangerous-keywords"],"backgroundTag":"sql-validation-rejected","analyzedSha":"fa42722fefe44265490dff2c27d79e2882bce4fa","analyzedAt":"2026-09-01T00:54:31.202Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}