security.test_sqli
Test web applications for SQL injection vulnerabilities by analyzing URL parameters to identify security weaknesses in database queries.
Instructions
Test for SQL injection vulnerabilities
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Target URL | |
| param | No | Parameter name to test | id |
Implementation Reference
- src/tools/security.ts:125-264 (registration)Registers the 'security.test_sqli' tool with schema and inline handler function in registerSecurityTools.server.tool( 'security.test_sqli', { description: 'Test for SQL injection vulnerabilities', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'Target URL' }, param: { type: 'string', description: 'Parameter name to test', default: 'id' }, }, required: ['url'], }, }, async ({ url, param = 'id' }: any): Promise<ToolResult> => { try { // Try sqlmap first if available const sqlmapExists = await runCommand('which', ['sqlmap']).then(() => true).catch(() => false); if (sqlmapExists) { try { const result = await runCommand('sqlmap', [ '-u', url, '-p', param, '--batch', '--risk=1', '--level=1', '--timeout=10', ], 60000); const vulnerable = result.stdout.includes('is vulnerable') || result.stdout.includes('injection'); if (vulnerable) { await saveFinding({ target: url, type: 'SQL Injection', severity: 'critical', description: `SQL injection vulnerability detected in parameter: ${param}`, payload: `sqlmap -u ${url} -p ${param}`, response: result.stdout.substring(0, 1000), timestamp: new Date(), score: 10, }); } return formatToolResult(true, { tool: 'sqlmap', vulnerable, output: result.stdout, }); } catch (e) { // Fall through to manual testing } } // Manual testing fallback const payloads = [ "' OR '1'='1", "' AND SLEEP(5)-- ", "1' UNION SELECT NULL--", "admin'--", ]; const results: SecurityTestResult[] = []; const startTime = Date.now(); for (const payload of payloads) { try { const testStart = Date.now(); const response = await axios.get(url, { params: { [param]: payload }, timeout: 20000, validateStatus: () => true, }); const testDuration = Date.now() - testStart; const body = typeof response.data === 'string' ? response.data : JSON.stringify(response.data); const errorIndicators = [ 'sql syntax', 'mysql', 'postgresql', 'ora-', 'sqlite', 'database error', ]; const hasError = errorIndicators.some((indicator) => body.toLowerCase().includes(indicator) ); const isTimeBased = payload.includes('SLEEP') && testDuration > 4000; const result: SecurityTestResult = { payload, response: { status: response.status, duration: testDuration, hasError, isTimeBased, }, }; if (hasError || isTimeBased) { result.vulnerability = 'SQL Injection'; result.severity = 'critical'; await saveFinding({ target: url, type: 'SQL Injection', severity: 'critical', description: `Potential SQL injection - error indicators or time-based delay detected`, payload, response: body.substring(0, 1000), timestamp: new Date(), score: 10, }); } results.push(result); } catch (error: any) { results.push({ payload, error: error.message, }); } } const sqliScore = results.some((r: any) => r.vulnerable) ? 9 : 4; await saveTestResult(url, 'sqli_test', true, { results }, undefined, sqliScore, param, JSON.stringify(results)); return formatToolResult(true, { results, summary: { totalTests: payloads.length, potentialVulns: results.filter((r) => r.vulnerability).length, }, }); } catch (error: any) { await saveTestResult(url, 'sqli_test', false, null, error.message, 0, param, undefined); return formatToolResult(false, null, error.message); } } );
- src/tools/security.ts:127-137 (schema)Input schema definition for the security.test_sqli tool, specifying url and optional param.{ description: 'Test for SQL injection vulnerabilities', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'Target URL' }, param: { type: 'string', description: 'Parameter name to test', default: 'id' }, }, required: ['url'], }, },
- src/tools/security.ts:138-263 (handler)The main handler function for security.test_sqli. Attempts SQLi detection using sqlmap if available, falls back to manual payload testing with error and time-based detection, saves findings, and returns ToolResult.async ({ url, param = 'id' }: any): Promise<ToolResult> => { try { // Try sqlmap first if available const sqlmapExists = await runCommand('which', ['sqlmap']).then(() => true).catch(() => false); if (sqlmapExists) { try { const result = await runCommand('sqlmap', [ '-u', url, '-p', param, '--batch', '--risk=1', '--level=1', '--timeout=10', ], 60000); const vulnerable = result.stdout.includes('is vulnerable') || result.stdout.includes('injection'); if (vulnerable) { await saveFinding({ target: url, type: 'SQL Injection', severity: 'critical', description: `SQL injection vulnerability detected in parameter: ${param}`, payload: `sqlmap -u ${url} -p ${param}`, response: result.stdout.substring(0, 1000), timestamp: new Date(), score: 10, }); } return formatToolResult(true, { tool: 'sqlmap', vulnerable, output: result.stdout, }); } catch (e) { // Fall through to manual testing } } // Manual testing fallback const payloads = [ "' OR '1'='1", "' AND SLEEP(5)-- ", "1' UNION SELECT NULL--", "admin'--", ]; const results: SecurityTestResult[] = []; const startTime = Date.now(); for (const payload of payloads) { try { const testStart = Date.now(); const response = await axios.get(url, { params: { [param]: payload }, timeout: 20000, validateStatus: () => true, }); const testDuration = Date.now() - testStart; const body = typeof response.data === 'string' ? response.data : JSON.stringify(response.data); const errorIndicators = [ 'sql syntax', 'mysql', 'postgresql', 'ora-', 'sqlite', 'database error', ]; const hasError = errorIndicators.some((indicator) => body.toLowerCase().includes(indicator) ); const isTimeBased = payload.includes('SLEEP') && testDuration > 4000; const result: SecurityTestResult = { payload, response: { status: response.status, duration: testDuration, hasError, isTimeBased, }, }; if (hasError || isTimeBased) { result.vulnerability = 'SQL Injection'; result.severity = 'critical'; await saveFinding({ target: url, type: 'SQL Injection', severity: 'critical', description: `Potential SQL injection - error indicators or time-based delay detected`, payload, response: body.substring(0, 1000), timestamp: new Date(), score: 10, }); } results.push(result); } catch (error: any) { results.push({ payload, error: error.message, }); } } const sqliScore = results.some((r: any) => r.vulnerable) ? 9 : 4; await saveTestResult(url, 'sqli_test', true, { results }, undefined, sqliScore, param, JSON.stringify(results)); return formatToolResult(true, { results, summary: { totalTests: payloads.length, potentialVulns: results.filter((r) => r.vulnerability).length, }, }); } catch (error: any) { await saveTestResult(url, 'sqli_test', false, null, error.message, 0, param, undefined); return formatToolResult(false, null, error.message); } }