Skip to main content
Glama
wordpress-plugin-audit.ts18.4 kB
/** * Plugin Template - Modern v4.2 (Single Source of Truth) * * Universal template that intelligently handles both single-file and multi-file analysis * Automatically detects analysis type based on provided parameters * * Copy this template for creating any new plugin - it adapts to your needs */ import { BasePlugin } from '../../plugins/base-plugin.js'; import { IPromptPlugin } from '../shared/types.js'; import { ThreeStagePromptManager } from '../../core/ThreeStagePromptManager.js'; import { PromptStages } from '../../types/prompt-stages.js'; import { withSecurity } from '../../security/integration-helpers.js'; import { readFileContent } from '../shared/helpers.js'; import { ModelSetup, ResponseProcessor, ParameterValidator, ErrorHandler, MultiFileAnalysis, TokenCalculator } from '../../utils/plugin-utilities.js'; import { getAnalysisCache } from '../../cache/index.js'; // Common Node.js modules - Use these instead of require() import { basename, dirname, extname, join, relative } from 'path'; import { readFile, stat, readdir } from 'fs/promises'; export class WordPressPluginAuditor extends BasePlugin implements IPromptPlugin { name = 'audit_wordpress_plugin'; category = 'analyze' as const; description = 'Comprehensive WordPress plugin audit - chains multiple analysis steps for security, performance, dependencies, and code quality'; // Universal parameter set - supports both single and multi-file scenarios parameters = { // Multi-file parameters (primary mode for plugin audit) projectPath: { type: 'string' as const, description: 'Path to WordPress plugin root directory', required: true }, // Analysis configuration auditDepth: { type: 'string' as const, description: 'Depth of audit analysis', enum: ['basic', 'detailed', 'comprehensive'], default: 'comprehensive', required: false }, auditType: { type: 'string' as const, description: 'Type of audit focus', enum: ['security', 'performance', 'quality', 'full-audit'], default: 'full-audit', required: false }, // Analysis step configuration includeSteps: { type: 'array' as const, description: 'Analysis steps to include in audit', required: false, items: { type: 'string' as const }, default: ['structure', 'dependencies', 'security', 'database', 'quality'] }, maxDepth: { type: 'number' as const, description: 'Maximum directory depth for analysis (1-5)', required: false, default: 4 }, // WordPress-specific context wpVersion: { type: 'string' as const, description: 'Target WordPress version for compatibility checks', required: false, default: '6.4' }, phpVersion: { type: 'string' as const, description: 'Target PHP version for compatibility checks', required: false, default: '8.0' } }; private analysisCache = getAnalysisCache(); private multiFileAnalysis = new MultiFileAnalysis(); private chainedResults: Map<string, any> = new Map(); constructor() { super(); // Cache and analysis utilities are initialized above } async execute(params: any, llmClient: any) { return await withSecurity(this, params, llmClient, async (secureParams) => { try { // 1. Validate WordPress plugin structure this.validateWordPressPlugin(secureParams); // 2. Setup model const { model, contextLength } = await ModelSetup.getReadyModel(llmClient); // 3. Execute chained analysis workflow return await this.executeChainedAnalysis(secureParams, llmClient, model, contextLength); } catch (error: any) { return ErrorHandler.createExecutionError('audit_wordpress_plugin', error); } }); } /** * Validate WordPress plugin structure */ private validateWordPressPlugin(params: any): void { ParameterValidator.validateProjectPath(params); ParameterValidator.validateDepth(params); ParameterValidator.validateEnum(params, 'auditType', ['security', 'performance', 'quality', 'full-audit']); ParameterValidator.validateEnum(params, 'auditDepth', ['basic', 'detailed', 'comprehensive']); } /** * Execute the chained analysis workflow */ private async executeChainedAnalysis(params: any, llmClient: any, model: any, contextLength: number) { const auditSteps = params.includeSteps || ['structure', 'dependencies', 'security', 'database', 'quality']; const results: Record<string, any> = {}; const stepExecutionLog: string[] = []; try { stepExecutionLog.push(`Starting WordPress plugin audit with ${auditSteps.length} steps`); // Step 1: Project Structure Overview if (auditSteps.includes('structure')) { stepExecutionLog.push('Executing: Project structure analysis'); results.structure = await this.runAnalysisStep('count_files', { projectPath: params.projectPath, analysisType: 'comprehensive', maxDepth: params.maxDepth }, llmClient); stepExecutionLog.push(`Structure analysis: ${results.structure.success ? 'SUCCESS' : 'FAILED'}`); } // Step 2: Dependencies Analysis if (auditSteps.includes('dependencies')) { stepExecutionLog.push('Executing: Dependencies analysis'); results.dependencies = await this.runAnalysisStep('analyze_dependencies', { projectPath: params.projectPath, analysisType: 'comprehensive', includePackageJson: true, checkDevDependencies: false }, llmClient); stepExecutionLog.push(`Dependencies analysis: ${results.dependencies.success ? 'SUCCESS' : 'FAILED'}`); } // Step 3: WordPress Security Audit if (auditSteps.includes('security')) { stepExecutionLog.push('Executing: WordPress security analysis'); results.security = await this.runAnalysisStep('analyze_wordpress_security', { projectPath: params.projectPath, wpType: 'plugin', wpVersion: params.wpVersion, analysisType: 'comprehensive', includeOwaspTop10: true }, llmClient); stepExecutionLog.push(`Security analysis: ${results.security.success ? 'SUCCESS' : 'FAILED'}`); } // Step 4: Database Query Analysis if (auditSteps.includes('database')) { stepExecutionLog.push('Executing: Database query analysis'); results.database = await this.runAnalysisStep('analyze_database_queries', { projectPath: params.projectPath, analysisType: 'comprehensive', context: { projectType: 'wordpress-plugin' } }, llmClient); stepExecutionLog.push(`Database analysis: ${results.database.success ? 'SUCCESS' : 'FAILED'}`); } // Step 5: Code Quality Assessment if (auditSteps.includes('quality')) { stepExecutionLog.push('Executing: Code quality analysis'); results.quality = await this.runAnalysisStep('analyze_code_quality', { projectPath: params.projectPath, analysisType: 'comprehensive', language: 'php' }, llmClient); stepExecutionLog.push(`Quality analysis: ${results.quality.success ? 'SUCCESS' : 'FAILED'}`); } // Step 6: Synthesize all results stepExecutionLog.push('Synthesizing comprehensive audit report'); const synthesizedResults = await this.synthesizeAuditResults({ ...results, executionLog: stepExecutionLog, completedSteps: auditSteps.filter(step => results[step]?.success), failedSteps: auditSteps.filter(step => results[step]?.success === false) }, params, model, contextLength); stepExecutionLog.push('Audit synthesis: COMPLETED'); return synthesizedResults; } catch (error: any) { stepExecutionLog.push(`Audit failed: ${error.message}`); return ErrorHandler.createExecutionError('audit_wordpress_plugin', error); } } /** * Run individual analysis step by calling other MCP functions */ private async runAnalysisStep(functionName: string, stepParams: any, llmClient: any): Promise<any> { try { // Check cache first const cacheKey = this.analysisCache.generateKey(functionName, stepParams, []); const cached = await this.analysisCache.get(cacheKey); if (cached) return cached; // Import the plugin loader to call other MCP functions const { PluginRegistry } = await import('../../plugins/index.js'); const pluginLoader = PluginRegistry.getInstance(); // Execute the specific analysis function let result; try { result = await pluginLoader.executePlugin(functionName, stepParams, llmClient); // Wrap successful results const wrappedResult = { stepName: functionName, parameters: stepParams, status: 'completed', timestamp: new Date().toISOString(), data: result.data || result, summary: `Completed ${functionName} analysis`, success: true }; // Cache the result await this.analysisCache.cacheAnalysis(cacheKey, wrappedResult, { modelUsed: result.modelUsed || 'unknown', executionTime: result.executionTimeMs || 0, timestamp: new Date().toISOString() }); return wrappedResult; } catch (pluginError: any) { // If the plugin doesn't exist or fails, return error result const errorResult = { stepName: functionName, status: 'failed', error: pluginError.message, timestamp: new Date().toISOString(), success: false }; return errorResult; } } catch (error: any) { return { stepName: functionName, status: 'system-error', error: error.message, timestamp: new Date().toISOString(), success: false }; } } /** * Synthesize all audit results into comprehensive report */ private async synthesizeAuditResults(results: Record<string, any>, params: any, model: any, contextLength: number) { // Generate final synthesis prompt stages const promptStages = this.getMultiFilePromptStages({ ...params, analysisResult: results, stepCount: Object.keys(results).length }); // Always use chunking for comprehensive synthesis const promptManager = new ThreeStagePromptManager(); const chunkSize = TokenCalculator.calculateOptimalChunkSize(promptStages, contextLength); const dataChunks = promptManager.chunkDataPayload(promptStages.dataPayload, chunkSize); const conversation = promptManager.createChunkedConversation(promptStages, dataChunks); const messages = [ conversation.systemMessage, ...conversation.dataMessages, conversation.analysisMessage ]; return await ResponseProcessor.executeChunked( messages, model, contextLength, 'audit_wordpress_plugin', 'multifile' ); } /** * Single-file mode not applicable for plugin audit */ private getSingleFilePromptStages(params: any): PromptStages { const systemAndContext = `WordPress Plugin Auditor - Single File Mode This mode is not recommended for WordPress plugin audits. Use multi-file mode with projectPath parameter for comprehensive plugin analysis.`; const dataPayload = `Single file analysis not supported for WordPress plugin audits. Please use projectPath parameter to analyze the entire plugin structure.`; const outputInstructions = `{ "error": "Single file mode not supported for WordPress plugin audits", "recommendation": "Use projectPath parameter for comprehensive plugin analysis" }`; return { systemAndContext, dataPayload, outputInstructions }; } /** * Multi-file prompt stages for comprehensive audit synthesis */ private getMultiFilePromptStages(params: any): PromptStages { const { analysisResult, auditType, auditDepth, wpVersion, phpVersion, stepCount } = params; const systemAndContext = `You are a senior WordPress plugin security and performance expert with 15+ years of experience auditing enterprise WordPress installations. **AUDIT CONTEXT:** - Audit Type: ${auditType} - Audit Depth: ${auditDepth} - Analysis Steps Completed: ${stepCount} - Target WordPress Version: ${wpVersion} - Target PHP Version: ${phpVersion} - Plugin Type: WordPress Plugin **YOUR EXPERTISE:** You are internationally recognized for: - WordPress plugin security auditing and penetration testing - Performance optimization for high-traffic WordPress sites - Code quality assessment for WordPress.org repository submissions - Database optimization and query performance analysis - Dependency management and conflict resolution **AUDIT METHODOLOGY:** 1. **Security Assessment**: OWASP Top 10, WordPress-specific vulnerabilities 2. **Performance Analysis**: Database queries, caching, resource usage 3. **Code Quality Review**: WordPress Coding Standards, best practices 4. **Dependency Analysis**: Plugin conflicts, version compatibility 5. **Architecture Review**: Plugin structure, hooks usage, extensibility **CRITICAL FOCUS AREAS:** - SQL injection vulnerabilities in custom queries - XSS vulnerabilities in admin interfaces and frontend output - CSRF protection through nonces validation - Capability and permission checks - Data sanitization and validation - Performance bottlenecks in database queries - Unused code and dependencies - WordPress API compliance and best practices`; const dataPayload = `**COMPREHENSIVE AUDIT RESULTS:** ${JSON.stringify(analysisResult, null, 2)}`; const outputInstructions = `**PROVIDE COMPREHENSIVE WORDPRESS PLUGIN AUDIT REPORT:** { "executiveSummary": { "overallRating": "critical|high-risk|medium-risk|low-risk|excellent", "primaryConcerns": ["concern1", "concern2", "concern3"], "strengths": ["strength1", "strength2"], "recommendedActions": ["action1", "action2"], "timeToFix": "immediate|1-2 days|1 week|2+ weeks" }, "securityAssessment": { "criticalVulnerabilities": [ { "type": "SQL Injection|XSS|CSRF|Authentication Bypass", "severity": "critical|high|medium|low", "location": "specific file and line", "description": "detailed vulnerability description", "exploit": "how this could be exploited", "fix": "specific fix with code example" } ], "securityScore": "A|B|C|D|F", "complianceIssues": ["OWASP issue 1", "WordPress security issue 2"] }, "performanceAssessment": { "databaseIssues": [ { "type": "N+1 Query|Missing Index|Inefficient Query|Direct SQL", "severity": "critical|high|medium|low", "location": "file and function", "impact": "performance impact description", "optimization": "specific optimization recommendation" } ], "performanceScore": "A|B|C|D|F", "bottlenecks": ["bottleneck1", "bottleneck2"], "optimizations": ["optimization1", "optimization2"] }, "codeQualityAssessment": { "wordpressStandards": { "compliance": "high|medium|low", "violations": ["violation1", "violation2"], "score": "A|B|C|D|F" }, "maintainability": { "score": "high|medium|low", "issues": ["issue1", "issue2"], "improvements": ["improvement1", "improvement2"] } }, "dependencyAssessment": { "unusedCode": ["unused file 1", "unused function 2"], "conflicts": ["potential conflict 1"], "outdatedDependencies": ["dependency1", "dependency2"], "recommendations": ["remove unused X", "update Y to version Z"] }, "actionPlan": { "immediate": [ { "priority": 1, "task": "fix critical security vulnerability", "estimatedTime": "2 hours", "risk": "critical" } ], "shortTerm": [ { "priority": 2, "task": "optimize database queries", "estimatedTime": "4 hours", "risk": "medium" } ], "longTerm": [ { "priority": 3, "task": "refactor architecture", "estimatedTime": "2 days", "risk": "low" } ] }, "complianceReport": { "wordpressOrgReady": true, "issuesBlocking": ["issue1", "issue2"], "recommendationsForSubmission": ["recommendation1", "recommendation2"] } } **REQUIREMENTS:** - Provide specific file names and line numbers for all issues - Include code examples for fixes where applicable - Prioritize findings by business impact and security risk - Ensure all recommendations are actionable and testable - Focus on WordPress-specific best practices and security guidelines`; return { systemAndContext, dataPayload, outputInstructions }; } /** * Backwards compatibility method */ getPromptStages(params: any): PromptStages { return this.getMultiFilePromptStages(params); } /** * Not used in plugin audit workflow */ private async discoverRelevantFiles(projectPath: string, maxDepth: number, analysisType: string): Promise<string[]> { const extensions = ['.php', '.js', '.css', '.json', '.xml', '.txt', '.md']; return await this.multiFileAnalysis.discoverFiles(projectPath, extensions, maxDepth); } /** * Not used in chained analysis workflow */ private async performMultiFileAnalysis(files: string[], params: any, model: any, contextLength: number): Promise<any> { return {}; } /** * Not used in chained analysis workflow */ private async analyzeIndividualFile(file: string, params: any, model: any): Promise<any> { return {}; } /** * WordPress plugin file extensions */ private getFileExtensions(analysisType: string): string[] { return ['.php', '.js', '.css', '.json', '.xml', '.txt', '.md', '.yml', '.yaml']; } private generateCacheKey(files: string[], params: any): string { const fileHash = files.join('|'); const paramHash = JSON.stringify(params); return `${fileHash}_${paramHash}`.substring(0, 64); } } export default WordPressPluginAuditor;

Implementation Reference

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/houtini-ai/lm'

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