Skip to main content
Glama

MCP Shamash

remediation-advisor.ts15.5 kB
import type { Finding } from '../types/index.js'; export interface RemediationAdvice { findingId: string; priority: 'immediate' | 'high' | 'medium' | 'low'; effort: 'trivial' | 'small' | 'medium' | 'large'; automaticFix?: string; manualSteps?: string[]; codeExample?: { before: string; after: string; }; references?: string[]; estimatedTime?: string; tools?: string[]; preventionTips?: string[]; } export interface RemediationPlan { findings: Finding[]; remediations: RemediationAdvice[]; summary: { totalFindings: number; autoFixable: number; immediateActions: number; estimatedEffort: string; }; prioritizedActions: { immediate: RemediationAdvice[]; high: RemediationAdvice[]; medium: RemediationAdvice[]; low: RemediationAdvice[]; }; } export class RemediationAdvisor { private remediationDatabase: Map<string, any>; constructor() { this.remediationDatabase = this.initializeRemediationDatabase(); } private initializeRemediationDatabase(): Map<string, any> { const db = new Map<string, any>(); // SQL Injection remediations db.set('sql_injection', { automaticFix: 'Use parameterized queries or prepared statements', manualSteps: [ 'Replace string concatenation with parameterized queries', 'Use ORM query builders instead of raw SQL', 'Validate and sanitize all user inputs', 'Apply principle of least privilege to database users', ], codeExample: { before: `query = "SELECT * FROM users WHERE id = " + userId;`, after: `query = "SELECT * FROM users WHERE id = ?"; preparedStatement.setString(1, userId);`, }, references: [ 'https://owasp.org/www-community/attacks/SQL_Injection', 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html', ], effort: 'small', estimatedTime: '30 minutes per query', tools: ['SQLMap', 'parameterized query libraries'], }); // XSS remediations db.set('xss', { automaticFix: 'Encode output and validate input', manualSteps: [ 'HTML encode all user-supplied data before rendering', 'Use Content Security Policy (CSP) headers', 'Validate input on server side', 'Use template engines with automatic escaping', ], codeExample: { before: `<div>\${userInput}</div>`, after: `<div>\${escapeHtml(userInput)}</div>`, }, references: [ 'https://owasp.org/www-community/attacks/xss/', 'https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html', ], effort: 'medium', estimatedTime: '1-2 hours per component', }); // Vulnerable dependency remediations db.set('vulnerable_dependency', { automaticFix: 'Update to patched version', manualSteps: [ 'Check for breaking changes in changelog', 'Update package version in manifest file', 'Run tests to ensure compatibility', 'Consider using automated dependency updates', ], tools: ['npm audit fix', 'pip-audit', 'cargo audit', 'Dependabot'], effort: 'trivial', estimatedTime: '5-15 minutes per dependency', }); // Hardcoded secrets remediations db.set('hardcoded_secret', { automaticFix: 'Move to environment variables or secret management', manualSteps: [ 'Remove secret from code immediately', 'Rotate the exposed credential', 'Use environment variables or secret management service', 'Add secret scanning to CI/CD pipeline', ], codeExample: { before: `const apiKey = "sk-1234567890abcdef";`, after: `const apiKey = process.env.API_KEY;`, }, tools: ['HashiCorp Vault', 'AWS Secrets Manager', 'Azure Key Vault', 'dotenv'], effort: 'small', estimatedTime: '30 minutes per secret', priority: 'immediate', }); // Weak cryptography remediations db.set('weak_crypto', { automaticFix: 'Use strong cryptographic algorithms', manualSteps: [ 'Replace MD5/SHA1 with SHA-256 or SHA-3', 'Use AES-256 for symmetric encryption', 'Implement proper key management', 'Use cryptographic libraries instead of custom implementations', ], codeExample: { before: `crypto.createHash('md5').update(password).digest('hex');`, after: `await bcrypt.hash(password, 10);`, }, references: [ 'https://owasp.org/www-project-cryptographic-storage-cheat-sheet/', ], effort: 'medium', estimatedTime: '2-4 hours', }); // Missing authentication remediations db.set('missing_auth', { automaticFix: 'Implement authentication middleware', manualSteps: [ 'Add authentication middleware to routes', 'Implement proper session management', 'Use OAuth2/JWT for API authentication', 'Add rate limiting to prevent brute force', ], codeExample: { before: `app.get('/api/admin', (req, res) => { /* ... */ });`, after: `app.get('/api/admin', requireAuth, requireRole('admin'), (req, res) => { /* ... */ });`, }, effort: 'large', estimatedTime: '4-8 hours', }); // Insecure configuration remediations db.set('insecure_config', { automaticFix: 'Apply security hardening configurations', manualSteps: [ 'Disable debug mode in production', 'Configure secure headers (HSTS, CSP, X-Frame-Options)', 'Enable HTTPS/TLS with strong ciphers', 'Disable unnecessary services and ports', ], tools: ['Security Headers scanner', 'TLS configuration generators'], effort: 'small', estimatedTime: '1-2 hours', }); return db; } async generateRemediationPlan(findings: Finding[]): Promise<RemediationPlan> { const remediations: RemediationAdvice[] = []; for (const finding of findings) { const advice = await this.generateRemediationAdvice(finding); remediations.push(advice); } // Categorize by priority const prioritizedActions = { immediate: remediations.filter(r => r.priority === 'immediate'), high: remediations.filter(r => r.priority === 'high'), medium: remediations.filter(r => r.priority === 'medium'), low: remediations.filter(r => r.priority === 'low'), }; // Calculate summary const autoFixable = remediations.filter(r => r.effort === 'trivial').length; const immediateActions = prioritizedActions.immediate.length; const totalEffort = this.calculateTotalEffort(remediations); return { findings, remediations, summary: { totalFindings: findings.length, autoFixable, immediateActions, estimatedEffort: totalEffort, }, prioritizedActions, }; } private async generateRemediationAdvice(finding: Finding): Promise<RemediationAdvice> { // Determine remediation type based on finding const remediationType = this.determineRemediationType(finding); const baseRemediation = this.remediationDatabase.get(remediationType); // Determine priority based on severity const priority = this.determinePriority(finding); // Build customized advice const advice: RemediationAdvice = { findingId: finding.id, priority, effort: baseRemediation?.effort || this.estimateEffort(finding), automaticFix: baseRemediation?.automaticFix, manualSteps: baseRemediation?.manualSteps, codeExample: baseRemediation?.codeExample, references: baseRemediation?.references || this.getDefaultReferences(finding.type), estimatedTime: baseRemediation?.estimatedTime || this.estimateTime(finding), tools: baseRemediation?.tools, preventionTips: this.generatePreventionTips(finding), }; // Customize advice based on specific finding details if (finding.type === 'dependency' && finding.cve) { advice.automaticFix = `Update to version that patches ${finding.cve}`; advice.references = [ `https://nvd.nist.gov/vuln/detail/${finding.cve}`, ...advice.references || [], ]; } if (finding.type === 'secret') { advice.priority = 'immediate'; // Secrets are always immediate priority advice.manualSteps = [ `Immediately rotate the exposed ${this.identifySecretType(finding.title)}`, ...advice.manualSteps || [], ]; } return advice; } private determineRemediationType(finding: Finding): string { const title = finding.title.toLowerCase(); const description = finding.description.toLowerCase(); const combined = `${title} ${description}`; if (combined.includes('sql') && combined.includes('injection')) { return 'sql_injection'; } if (combined.includes('xss') || combined.includes('cross-site scripting')) { return 'xss'; } if (finding.type === 'dependency' || combined.includes('vulnerable') || combined.includes('cve')) { return 'vulnerable_dependency'; } if (finding.type === 'secret' || combined.includes('hardcoded') || combined.includes('api key')) { return 'hardcoded_secret'; } if (combined.includes('weak') && (combined.includes('crypto') || combined.includes('hash'))) { return 'weak_crypto'; } if (combined.includes('authentication') || combined.includes('authorization')) { return 'missing_auth'; } if (finding.type === 'infrastructure' || combined.includes('configuration')) { return 'insecure_config'; } return 'generic'; } private determinePriority(finding: Finding): 'immediate' | 'high' | 'medium' | 'low' { switch (finding.severity) { case 'critical': return 'immediate'; case 'high': return 'high'; case 'medium': return 'medium'; case 'low': case 'informational': return 'low'; default: return 'medium'; } } private estimateEffort(finding: Finding): 'trivial' | 'small' | 'medium' | 'large' { if (finding.type === 'dependency') return 'trivial'; if (finding.type === 'secret') return 'small'; if (finding.type === 'infrastructure') return 'small'; if (finding.severity === 'critical') return 'large'; if (finding.severity === 'high') return 'medium'; return 'small'; } private estimateTime(finding: Finding): string { const effort = this.estimateEffort(finding); switch (effort) { case 'trivial': return '5-15 minutes'; case 'small': return '30-60 minutes'; case 'medium': return '2-4 hours'; case 'large': return '4-8 hours'; default: return '1-2 hours'; } } private calculateTotalEffort(remediations: RemediationAdvice[]): string { const effortMap = { trivial: 0.25, small: 1, medium: 3, large: 6, }; const totalHours = remediations.reduce((sum, r) => { return sum + (effortMap[r.effort] || 1); }, 0); if (totalHours < 8) { return `${Math.ceil(totalHours)} hours`; } else { return `${Math.ceil(totalHours / 8)} days`; } } private identifySecretType(title: string): string { const lower = title.toLowerCase(); if (lower.includes('api')) return 'API key'; if (lower.includes('token')) return 'token'; if (lower.includes('password')) return 'password'; if (lower.includes('credential')) return 'credential'; if (lower.includes('secret')) return 'secret'; return 'credential'; } private getDefaultReferences(findingType: string): string[] { const references: Record<string, string[]> = { sast: ['https://owasp.org/www-project-top-ten/'], dependency: ['https://owasp.org/www-project-dependency-check/'], secret: ['https://owasp.org/www-community/vulnerabilities/Use_of_hard-coded_password'], infrastructure: ['https://www.cisecurity.org/cis-benchmarks/'], dast: ['https://owasp.org/www-project-web-security-testing-guide/'], }; return references[findingType] || ['https://owasp.org/']; } private generatePreventionTips(finding: Finding): string[] { const tips: string[] = []; switch (finding.type) { case 'sast': tips.push('Implement secure coding practices'); tips.push('Use static analysis in CI/CD pipeline'); tips.push('Conduct regular code reviews'); break; case 'dependency': tips.push('Enable automated dependency updates'); tips.push('Monitor security advisories'); tips.push('Use dependency scanning in CI/CD'); break; case 'secret': tips.push('Use secret management systems'); tips.push('Implement pre-commit hooks for secret scanning'); tips.push('Regular credential rotation policy'); break; case 'infrastructure': tips.push('Use Infrastructure as Code (IaC) scanning'); tips.push('Implement configuration baselines'); tips.push('Regular security audits'); break; } return tips; } generateMarkdownReport(plan: RemediationPlan): string { const md: string[] = []; md.push('# Security Remediation Plan\n'); md.push(`Generated: ${new Date().toISOString()}\n`); md.push('## Summary\n'); md.push(`- **Total Findings**: ${plan.summary.totalFindings}`); md.push(`- **Auto-fixable**: ${plan.summary.autoFixable}`); md.push(`- **Immediate Actions Required**: ${plan.summary.immediateActions}`); md.push(`- **Estimated Total Effort**: ${plan.summary.estimatedEffort}\n`); // Immediate actions if (plan.prioritizedActions.immediate.length > 0) { md.push('## 🚨 Immediate Actions Required\n'); for (const action of plan.prioritizedActions.immediate) { md.push(`### Finding: ${action.findingId}`); if (action.automaticFix) { md.push(`**Quick Fix**: ${action.automaticFix}`); } if (action.manualSteps) { md.push('**Steps**:'); action.manualSteps.forEach(step => md.push(`1. ${step}`)); } md.push(`**Estimated Time**: ${action.estimatedTime}\n`); } } // High priority if (plan.prioritizedActions.high.length > 0) { md.push('## ⚠️ High Priority\n'); for (const action of plan.prioritizedActions.high) { md.push(`- **${action.findingId}**: ${action.automaticFix || 'Manual fix required'} (${action.estimatedTime})`); } md.push(''); } // Code examples const withExamples = plan.remediations.filter(r => r.codeExample); if (withExamples.length > 0) { md.push('## Code Examples\n'); for (const action of withExamples.slice(0, 3)) { md.push(`### ${action.findingId}\n`); md.push('**Before**:'); md.push('```javascript'); md.push(action.codeExample!.before); md.push('```\n'); md.push('**After**:'); md.push('```javascript'); md.push(action.codeExample!.after); md.push('```\n'); } } // Useful tools const allTools = new Set<string>(); plan.remediations.forEach(r => r.tools?.forEach(t => allTools.add(t))); if (allTools.size > 0) { md.push('## Recommended Tools\n'); Array.from(allTools).forEach(tool => md.push(`- ${tool}`)); } return md.join('\n'); } }

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/NeoTecDigital/mcp_shamash'

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