UNPKG

npm-api-analyzer

Version:

CLI tool to analyze npm packages for network API usage, prototype pollution, and security vulnerabilities

100 lines (99 loc) 4.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Reporter = void 0; const markdownReporter_1 = require("./markdownReporter"); class Reporter { static generateReport(result) { const { packageName, version, apiUsages, summary } = result; let report = `\n=== NPM Security Analysis Report ===\n`; report += `Package: ${packageName}@${version}\n`; report += `Analysis Date: ${new Date().toISOString()}\n\n`; report += `SUMMARY:\n`; report += ` Total APIs Found: ${summary.totalAPIs}\n`; report += ` Network APIs: ${summary.categories.network}\n`; report += ` DOM Operations: ${summary.categories.dom}\n`; report += ` Dynamic JS: ${summary.categories.dynamicJs}\n`; report += ` Risk Level: ${summary.riskLevel.toUpperCase()}\n\n`; if (summary.totalAPIs > 0) { report += `API Types Distribution:\n`; Object.entries(summary.apiTypes).forEach(([type, count]) => { report += ` ${type}: ${count}\n`; }); report += `\n`; report += `DETAILED FINDINGS:\n`; const groupedAPIs = this.groupAPIsByType(apiUsages); Object.entries(groupedAPIs).forEach(([type, apis]) => { report += `\n${type.toUpperCase()} APIs (${apis.length}):\n`; apis.forEach(api => { report += ` ✓ ${api.api} [${api.riskLevel.toUpperCase()} RISK]\n`; report += ` Location: ${api.location.file}:${api.location.line}:${api.location.column}\n`; report += ` Context: ${api.context.currentLine}\n\n`; }); }); } else { report += `✅ No suspicious API usage detected in this package.\n`; } report += `\nRisk Assessment:\n`; report += this.generateRiskAssessment(result); return report; } static generateMarkdownReport(result) { return markdownReporter_1.MarkdownReporter.generateMarkdownReport(result); } static groupAPIsByType(apis) { const grouped = {}; apis.forEach(api => { if (!grouped[api.type]) { grouped[api.type] = []; } grouped[api.type].push(api); }); return grouped; } static generateRiskAssessment(result) { const { summary } = result; let assessment = ''; switch (summary.riskLevel) { case 'low': assessment = '🟢 LOW: Package has minimal security concerns.\n'; break; case 'medium': assessment = '🟡 MEDIUM: Package has some security risks. Review usage carefully.\n'; break; case 'high': assessment = '🔴 HIGH: Package has significant security risks. Requires thorough review.\n'; break; } if (summary.riskFactors.length > 0) { assessment += '\nRisk Factors:\n'; summary.riskFactors.forEach(factor => { assessment += `• ${factor}\n`; }); } assessment += '\nRecommendations:\n'; if (summary.categories.dynamicJs > 0) { assessment += '• Audit all dynamic JavaScript execution carefully\n'; } if (summary.apiTypes.xhr || summary.apiTypes.fetch) { assessment += '• Review network requests for data exfiltration risks\n'; } if (summary.apiTypes.websocket) { assessment += '• Check WebSocket connections for unauthorized communication\n'; } if (summary.apiTypes.node) { assessment += '• Verify server-side HTTP requests are legitimate\n'; } if (summary.apiTypes['dom-manipulation']) { assessment += '• Examine DOM manipulation for potential XSS vectors\n'; } if (summary.totalAPIs > 10) { assessment += '• Consider using a more lightweight alternative\n'; } return assessment; } static generateJSONReport(result) { return JSON.stringify(result, null, 2); } } exports.Reporter = Reporter;