npm-api-analyzer
Version:
CLI tool to analyze npm packages for network API usage, prototype pollution, and security vulnerabilities
96 lines (95 loc) • 3.83 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.NPMSecurityAnalyzer = void 0;
const packageDownloader_1 = require("./packageDownloader");
const fileAnalyzer_1 = require("./fileAnalyzer");
class NPMSecurityAnalyzer {
constructor(tempDir) {
this.packageDownloader = new packageDownloader_1.PackageDownloader(tempDir);
this.fileAnalyzer = new fileAnalyzer_1.FileAnalyzer();
}
async analyzePackage(packageName, version) {
console.log(`Analyzing package: ${packageName}@${version}`);
try {
// Get package info
const packageInfo = await this.packageDownloader.getPackageInfo(packageName, version);
console.log(`Downloaded package info for ${packageName}@${version}`);
// Download package
const packageDir = await this.packageDownloader.downloadPackage(packageInfo);
console.log(`Extracted package to: ${packageDir}`);
// Analyze files
const apiUsages = await this.fileAnalyzer.analyzeDirectory(packageDir);
console.log(`Found ${apiUsages.length} API usages`);
// Generate analysis result
const result = {
packageName,
version,
apiUsages,
summary: this.generateSummary(apiUsages)
};
return result;
}
catch (error) {
throw new Error(`Failed to analyze package ${packageName}@${version}: ${error}`);
}
}
generateSummary(apiUsages) {
const apiTypes = {};
const categories = {
network: 0,
dom: 0,
dynamicJs: 0,
prototypePollution: 0
};
const riskFactors = [];
apiUsages.forEach(api => {
apiTypes[api.type] = (apiTypes[api.type] || 0) + 1;
// Map category names to object keys
const categoryKey = api.category === 'dynamic-js' ? 'dynamicJs' :
api.category === 'prototype-pollution' ? 'prototypePollution' :
api.category;
if (categoryKey in categories) {
categories[categoryKey]++;
}
// Collect risk factors
if (api.riskLevel === 'high') {
riskFactors.push(`High-risk ${api.category} API: ${api.api}`);
}
});
const totalAPIs = apiUsages.length;
let riskLevel = 'low';
// Determine risk level based on total APIs and high-risk APIs
const highRiskAPIs = apiUsages.filter(api => api.riskLevel === 'high').length;
const mediumRiskAPIs = apiUsages.filter(api => api.riskLevel === 'medium').length;
if (highRiskAPIs > 0 || totalAPIs > 20) {
riskLevel = 'high';
}
else if (mediumRiskAPIs > 0 || totalAPIs > 5) {
riskLevel = 'medium';
}
// Additional risk factors
if (categories.dynamicJs > 0) {
riskFactors.push(`Dynamic JavaScript execution detected (${categories.dynamicJs} instances)`);
}
if (categories.network > 10) {
riskFactors.push(`High network activity (${categories.network} network APIs)`);
}
if (categories.dom > 0) {
riskFactors.push(`DOM manipulation capabilities (${categories.dom} instances)`);
}
if (categories.prototypePollution > 0) {
riskFactors.push(`Prototype pollution risks detected (${categories.prototypePollution} instances)`);
}
return {
totalAPIs,
categories,
apiTypes,
riskLevel,
riskFactors
};
}
cleanup() {
this.packageDownloader.cleanup();
}
}
exports.NPMSecurityAnalyzer = NPMSecurityAnalyzer;
;