@@ -65,15 +65,24 @@ export default class QueryExecutionService {
6565 }
6666
6767 try {
68+ // Safety check: Enforce a firm limit on results to prevent OOM
69+ let finalSql = sql . trim ( )
70+ if ( ds . type === 'mysql' || ds . type === 'postgresql' ) {
71+ finalSql = finalSql . replace ( / ; $ / , '' )
72+ if ( ! / \b L I M I T \b / i. test ( finalSql ) ) {
73+ finalSql += ' LIMIT 1000'
74+ }
75+ }
76+
6877 if ( ds . type === 'mysql' ) {
69- const { result, values } = replaceVars ( sql , inputParams , 'sql' )
78+ const { result, values } = replaceVars ( finalSql , inputParams , 'sql' )
7079 executedSql = result
7180 const { client } = await DbHelper . getRawConnection ( ds . id , timeout )
7281 const [ rows ] = await ( client as any ) . execute ( { sql : executedSql , values, timeout } )
7382 await client . end ( )
7483 queryResults = rows
7584 } else if ( ds . type === 'postgresql' ) {
76- const { result, values } = replaceVars ( sql , inputParams , 'pg' )
85+ const { result, values } = replaceVars ( finalSql , inputParams , 'pg' )
7786 executedSql = result
7887 const { client } = await DbHelper . getRawConnection ( ds . id , timeout )
7988 try {
@@ -97,6 +106,14 @@ export default class QueryExecutionService {
97106 )
98107 }
99108
109+ // --- Phase 3: Critical Security Guard against Command Injection (RCE) ---
110+ // Block all bash control operators, pipeline characters, command substitutions,
111+ // environment variable access, and dangerous redirections to ensure `curl` cannot be escaped.
112+ const forbiddenBashShellChars = / [ ; & | $ ` \n < > ] /
113+ if ( forbiddenBashShellChars . test ( commandToExecute ) ) {
114+ throw new Error ( `Command validation failed: Command contains forbidden shell meta-characters. Potential Command Injection isolated.` )
115+ }
116+
100117 const { stdout } = await execAsync ( executedSql , {
101118 timeout,
102119 maxBuffer : 10 * 1024 * 1024 ,
0 commit comments