This Node.js script uses Puppeteer and OWASP ZAP API to scan a list of URLs (from "urls.json") for security vulnerabilities. It visits each URL, triggers ZAP scans, and appends alerts along with the URL found to a newline-delimited JSON file ("zap-report.jsonl").
import express from "express";
import { launch } from "puppeteer";
const proxyChain = require("proxy-chain");
import { URLSearchParams } from "node:url";
import fetch from "node-fetch";
import { appendFile } from "fs/promises";
import urls from "./urls.json";
import { ScanResults } from "./zap.type";
express().listen(process.env.PORT || 4000);
const zapApiUrl = "http://127.0.0.1:8080";
const zapApiKey = "xxxxxxxxxxxxxxxxxxxxxxx";
async function getZapResults(url: string): Promise<ScanResults> {
await clearAllAlerts();
const anonymizedProxy = await proxyChain.anonymizeProxy(zapApiUrl);
const browser = await launch({
args: [`--proxy-server=${anonymizedProxy}`],
ignoreHTTPSErrors: true,
headless: "new",
});
const page = await browser.newPage();
await page.goto(url);
await page.close();
await browser.close();
await poll(fetchScans, hasRecordsLeft, 1000);
const params = new URLSearchParams({ apikey: zapApiKey });
const res = await fetch(`${zapApiUrl}/JSON/alert/view/alerts/?${params}`);
return res.json();
}
const clearAllAlerts = async () => {
const params = new URLSearchParams({ apikey: zapApiKey });
await fetch(`${zapApiUrl}/JSON/alert/action/deleteAllAlerts?${params}`);
};
const fetchScans = async () => {
const params = new URLSearchParams({ apikey: zapApiKey });
const res = await fetch(`${zapApiUrl}/JSON/pscan/view/recordsToScan?${params}`);
return res.json();
};
const hasRecordsLeft = (results: any) => results.recordsToScan !== "0";
const poll = async function (fn: Function, fnCondition: Function, ms: number) {
let result = await fn();
while (fnCondition(result)) {
await wait(ms);
result = await fn();
}
return result;
};
const wait = (ms = 1000) => new Promise(res => setTimeout(res, ms));
(async () => {
for await (const url of urls) {
const { alerts } = await getZapResults(url);
const withFoundAt = alerts.map(alert => ({ ...alert, foundAt: url }));
await appendFile("zap-report.jsonl", `${withFoundAt.map(v => JSON.stringify(v)).join("\n")}\n`);
}
})();