Skip to main content
Glama

js.extract_secrets

Extract potential API keys, tokens, and secrets from JavaScript source code using heuristic analysis for security testing.

Instructions

Heuristically extract potential API keys, tokens, and secrets from JS

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sourceYesJavaScript source code

Implementation Reference

  • The main handler function that heuristically extracts potential API keys, tokens, AWS keys, Google API keys, and secret candidates from JavaScript source code using various regex patterns. It categorizes and deduplicates findings and returns a structured result.
    async ({ source }: any): Promise<ToolResult> => { try { const secrets: any = { apiKeys: [], tokens: [], passwords: [], awsKeys: [], googleKeys: [], candidates: [], }; // API Key patterns const apiKeyPatterns = [ /(?:api[_-]?key|apikey)[\s:=]+["'`]([A-Za-z0-9_\-]{20,})["'`]/gi, /(?:secret[_-]?key|secretkey)[\s:=]+["'`]([A-Za-z0-9_\-]{20,})["'`]/gi, ]; // Token patterns const tokenPatterns = [ /(?:token|access[_-]?token)[\s:=]+["'`]([A-Za-z0-9_\-]{20,})["'`]/gi, /(?:bearer|authorization)[\s:]+["'`]?([A-Za-z0-9_\-\.]{20,})["'`]?/gi, ]; // AWS keys const awsPattern = /AKIA[0-9A-Z]{16}/g; // Google API keys const googlePattern = /AIza[0-9A-Za-z\-_]{35}/g; // Extract matches apiKeyPatterns.forEach((pattern) => { let match: RegExpExecArray | null; while ((match = pattern.exec(source)) !== null) { secrets.apiKeys.push(match[1]); } }); tokenPatterns.forEach((pattern) => { let match: RegExpExecArray | null; while ((match = pattern.exec(source)) !== null) { secrets.tokens.push(match[1]); } }); const awsMatches = source.match(awsPattern) || []; secrets.awsKeys = Array.from(new Set(awsMatches)); const googleMatches = source.match(googlePattern) || []; secrets.googleKeys = Array.from(new Set(googleMatches)); // General long strings that might be secrets const candidatePattern = /["'`]([A-Za-z0-9_\-]{32,})["'`]/g; let candidateMatch: RegExpExecArray | null; while ((candidateMatch = candidatePattern.exec(source)) !== null) { const candidate = candidateMatch[1]; // Filter out URLs and common false positives if ( !candidate.startsWith('http') && !candidate.includes('/') && candidate.length < 200 ) { secrets.candidates.push(candidate); } } // Deduplicate secrets.apiKeys = Array.from(new Set(secrets.apiKeys)); secrets.tokens = Array.from(new Set(secrets.tokens)); secrets.candidates = Array.from(new Set(secrets.candidates)).slice(0, 50); return formatToolResult(true, { ...secrets, summary: { totalApiKeys: secrets.apiKeys.length, totalTokens: secrets.tokens.length, totalAwsKeys: secrets.awsKeys.length, totalGoogleKeys: secrets.googleKeys.length, totalCandidates: secrets.candidates.length, }, }); } catch (error: any) { return formatToolResult(false, null, error.message); } }
  • The input schema for the tool, requiring a 'source' string parameter containing the JavaScript code to analyze.
    { description: 'Heuristically extract potential API keys, tokens, and secrets from JS', inputSchema: { type: 'object', properties: { source: { type: 'string', description: 'JavaScript source code' }, }, required: ['source'], }, },
  • The server.tool() call that registers the 'js.extract_secrets' tool with its schema and inline handler function.
    'js.extract_secrets', { description: 'Heuristically extract potential API keys, tokens, and secrets from JS', inputSchema: { type: 'object', properties: { source: { type: 'string', description: 'JavaScript source code' }, }, required: ['source'], }, }, async ({ source }: any): Promise<ToolResult> => { try { const secrets: any = { apiKeys: [], tokens: [], passwords: [], awsKeys: [], googleKeys: [], candidates: [], }; // API Key patterns const apiKeyPatterns = [ /(?:api[_-]?key|apikey)[\s:=]+["'`]([A-Za-z0-9_\-]{20,})["'`]/gi, /(?:secret[_-]?key|secretkey)[\s:=]+["'`]([A-Za-z0-9_\-]{20,})["'`]/gi, ]; // Token patterns const tokenPatterns = [ /(?:token|access[_-]?token)[\s:=]+["'`]([A-Za-z0-9_\-]{20,})["'`]/gi, /(?:bearer|authorization)[\s:]+["'`]?([A-Za-z0-9_\-\.]{20,})["'`]?/gi, ]; // AWS keys const awsPattern = /AKIA[0-9A-Z]{16}/g; // Google API keys const googlePattern = /AIza[0-9A-Za-z\-_]{35}/g; // Extract matches apiKeyPatterns.forEach((pattern) => { let match: RegExpExecArray | null; while ((match = pattern.exec(source)) !== null) { secrets.apiKeys.push(match[1]); } }); tokenPatterns.forEach((pattern) => { let match: RegExpExecArray | null; while ((match = pattern.exec(source)) !== null) { secrets.tokens.push(match[1]); } }); const awsMatches = source.match(awsPattern) || []; secrets.awsKeys = Array.from(new Set(awsMatches)); const googleMatches = source.match(googlePattern) || []; secrets.googleKeys = Array.from(new Set(googleMatches)); // General long strings that might be secrets const candidatePattern = /["'`]([A-Za-z0-9_\-]{32,})["'`]/g; let candidateMatch: RegExpExecArray | null; while ((candidateMatch = candidatePattern.exec(source)) !== null) { const candidate = candidateMatch[1]; // Filter out URLs and common false positives if ( !candidate.startsWith('http') && !candidate.includes('/') && candidate.length < 200 ) { secrets.candidates.push(candidate); } } // Deduplicate secrets.apiKeys = Array.from(new Set(secrets.apiKeys)); secrets.tokens = Array.from(new Set(secrets.tokens)); secrets.candidates = Array.from(new Set(secrets.candidates)).slice(0, 50); return formatToolResult(true, { ...secrets, summary: { totalApiKeys: secrets.apiKeys.length, totalTokens: secrets.tokens.length, totalAwsKeys: secrets.awsKeys.length, totalGoogleKeys: secrets.googleKeys.length, totalCandidates: secrets.candidates.length, }, }); } catch (error: any) { return formatToolResult(false, null, error.message); } } );

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