npm-api-analyzer
Version:
CLI tool to analyze npm packages for network API usage, prototype pollution, and security vulnerabilities
87 lines (86 loc) • 5.03 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NetworkAPIDetector = void 0;
class NetworkAPIDetector {
static detectNetworkAPIs(content, filename) {
const results = [];
const lines = content.split('\n');
for (const { pattern, type, api } of this.NETWORK_PATTERNS) {
let match;
while ((match = pattern.exec(content)) !== null) {
const lineNumber = this.getLineNumber(content, match.index);
const columnNumber = this.getColumnNumber(content, match.index);
const contextLine = lines[lineNumber - 1] || '';
results.push({
type,
api,
location: {
file: filename,
line: lineNumber,
column: columnNumber
},
context: contextLine.trim()
});
}
}
return results;
}
static getLineNumber(content, index) {
return content.substring(0, index).split('\n').length;
}
static getColumnNumber(content, index) {
const lines = content.substring(0, index).split('\n');
return lines[lines.length - 1].length + 1;
}
}
exports.NetworkAPIDetector = NetworkAPIDetector;
NetworkAPIDetector.NETWORK_PATTERNS = [
// Fetch API
{ pattern: /\bfetch\s*\(/g, type: 'fetch', api: 'fetch()' },
{ pattern: /\bwindow\.fetch\s*\(/g, type: 'fetch', api: 'window.fetch()' },
{ pattern: /\bglobalThis\.fetch\s*\(/g, type: 'fetch', api: 'globalThis.fetch()' },
// XMLHttpRequest
{ pattern: /\bnew\s+XMLHttpRequest\s*\(/g, type: 'xhr', api: 'new XMLHttpRequest()' },
{ pattern: /\bXMLHttpRequest\s*\(/g, type: 'xhr', api: 'XMLHttpRequest()' },
{ pattern: /\bwindow\.XMLHttpRequest\s*\(/g, type: 'xhr', api: 'window.XMLHttpRequest()' },
// WebSocket
{ pattern: /\bnew\s+WebSocket\s*\(/g, type: 'websocket', api: 'new WebSocket()' },
{ pattern: /\bWebSocket\s*\(/g, type: 'websocket', api: 'WebSocket()' },
{ pattern: /\bwindow\.WebSocket\s*\(/g, type: 'websocket', api: 'window.WebSocket()' },
// DOM APIs for network requests
{ pattern: /\bdocument\.createElement\s*\(\s*['"`]script['"`]\s*\)/g, type: 'dom', api: 'document.createElement("script")' },
{ pattern: /\bdocument\.createElement\s*\(\s*['"`]img['"`]\s*\)/g, type: 'dom', api: 'document.createElement("img")' },
{ pattern: /\bdocument\.createElement\s*\(\s*['"`]link['"`]\s*\)/g, type: 'dom', api: 'document.createElement("link")' },
{ pattern: /\bdocument\.createElement\s*\(\s*['"`]iframe['"`]\s*\)/g, type: 'dom', api: 'document.createElement("iframe")' },
{ pattern: /\bnew\s+Image\s*\(/g, type: 'dom', api: 'new Image()' },
{ pattern: /\bwindow\.Image\s*\(/g, type: 'dom', api: 'window.Image()' },
// Node.js APIs
{ pattern: /\brequire\s*\(\s*['"`]https?['"`]\s*\)/g, type: 'node', api: 'require("http/https")' },
{ pattern: /\brequire\s*\(\s*['"`]node-fetch['"`]\s*\)/g, type: 'node', api: 'require("node-fetch")' },
{ pattern: /\brequire\s*\(\s*['"`]axios['"`]\s*\)/g, type: 'node', api: 'require("axios")' },
{ pattern: /\brequire\s*\(\s*['"`]request['"`]\s*\)/g, type: 'node', api: 'require("request")' },
{ pattern: /\bimport\s+.*\s+from\s+['"`]node-fetch['"`]/g, type: 'node', api: 'import from "node-fetch"' },
{ pattern: /\bimport\s+.*\s+from\s+['"`]axios['"`]/g, type: 'node', api: 'import from "axios"' },
{ pattern: /\bimport\s+.*\s+from\s+['"`]https?['"`]/g, type: 'node', api: 'import from "http/https"' },
// Dynamic imports and requires
{ pattern: /\bimport\s*\(\s*['"`][^'"`]*fetch[^'"`]*['"`]\s*\)/g, type: 'node', api: 'dynamic import fetch' },
{ pattern: /\brequire\s*\(\s*['"`][^'"`]*fetch[^'"`]*['"`]\s*\)/g, type: 'node', api: 'dynamic require fetch' },
// Other common network libraries
{ pattern: /\bsuperagent\b/g, type: 'other', api: 'superagent' },
{ pattern: /\bgot\b/g, type: 'other', api: 'got' },
{ pattern: /\bundici\b/g, type: 'other', api: 'undici' },
{ pattern: /\bsocket\.io\b/g, type: 'other', api: 'socket.io' },
{ pattern: /\bws\b/g, type: 'other', api: 'ws' },
// URL objects (potential network usage)
{ pattern: /\bnew\s+URL\s*\(/g, type: 'other', api: 'new URL()' },
{ pattern: /\bURL\s*\(/g, type: 'other', api: 'URL()' },
{ pattern: /\bwindow\.URL\s*\(/g, type: 'other', api: 'window.URL()' },
// EventSource (Server-Sent Events)
{ pattern: /\bnew\s+EventSource\s*\(/g, type: 'other', api: 'new EventSource()' },
{ pattern: /\bEventSource\s*\(/g, type: 'other', api: 'EventSource()' },
// Navigator APIs
{ pattern: /\bnavigator\.sendBeacon\s*\(/g, type: 'other', api: 'navigator.sendBeacon()' },
// Service Worker/Cache APIs
{ pattern: /\bcaches\./g, type: 'other', api: 'Cache API' },
{ pattern: /\bserviceWorker\./g, type: 'other', api: 'Service Worker API' },
];