From a3d7869877cdc9b1fcf8d8a9c5a3a44bd6346967 Mon Sep 17 00:00:00 2001 From: Sefinek Date: Sat, 7 Sep 2024 00:18:16 +0200 Subject: [PATCH] Bug fixes (1.1.1) --- index.js | 18 +++++++++--------- package-lock.json | 18 +++++++++--------- package.json | 4 ++-- scripts/csv.js | 20 ++++++++++---------- scripts/sefinekAPI.js | 4 ++-- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/index.js b/index.js index 123ba76..0baa22b 100644 --- a/index.js +++ b/index.js @@ -30,7 +30,7 @@ const fetchBlockedIPs = async () => { }; const isIPReportedRecently = (ip, reportedIPs) => { - const lastReport = reportedIPs.find(entry => entry.ip === ip && (entry.action === 'Reported' || entry.action.startsWith('Failed'))); + const lastReport = reportedIPs.find(entry => entry.ip === ip && (entry.action === 'REPORTED' || entry.action.startsWith('TOO_MANY_REQUESTS'))); if (lastReport) { const lastTimestamp = new Date(lastReport.timestamp).getTime(); const currentTime = Date.now(); @@ -41,23 +41,23 @@ const isIPReportedRecently = (ip, reportedIPs) => { return { recentlyReported: false }; }; -const reportIP = async (event, hostname, endpoint, userAgent, country, cycleErrorCounts) => { +const reportIP = async (event, country, hostname, endpoint, userAgent, cycleErrorCounts) => { const uri = `${hostname}${endpoint}`; if (!uri) { - logToCSV(event.rayName, event.clientIP, hostname, endpoint, event.userAgent, 'Failed - Missing URL', country); + logToCSV(event.rayName, event.clientIP, country, hostname, endpoint, event.userAgent, 'MISSING_URI'); log('warn', `Missing URL ${event.clientIP}; URI: ${uri}`); return false; } if (event.clientIP === clientIp.address) { - logToCSV(event.rayName, event.clientIP, hostname, endpoint, event.userAgent, 'Your IP address', country); + logToCSV(event.rayName, event.clientIP, country, hostname, endpoint, event.userAgent, 'YOUR_IP_ADDRESS'); log('log', `Your IP address (${event.clientIP}) was unexpectedly received from Cloudflare. URI: ${uri}; Ignoring...`); return false; } if (uri.length > MAX_URL_LENGTH) { - logToCSV(event.rayName, event.clientIP, hostname, endpoint, event.userAgent, 'Failed - URL too long', country); + logToCSV(event.rayName, event.clientIP, country, hostname, endpoint, event.userAgent, 'URI_TOO_LONG'); log('log', `URL too long ${event.clientIP}; URI: ${uri}`); return false; } @@ -69,13 +69,13 @@ const reportIP = async (event, hostname, endpoint, userAgent, country, cycleErro comment: generateComment(event) }, { headers: headers.ABUSEIPDB }); - logToCSV(event.rayName, event.clientIP, hostname, endpoint, event.userAgent, 'Reported', country); + logToCSV(event.rayName, event.clientIP, country, hostname, endpoint, event.userAgent, 'REPORTED'); log('log', `Reported ${event.clientIP}; URI: ${uri}`); return true; } catch (err) { if (err.response?.status === 429) { - logToCSV(event.rayName, event.clientIP, hostname, endpoint, event.userAgent, 'Failed - 429 Too Many Requests', country); + logToCSV(event.rayName, event.clientIP, country, hostname, endpoint, event.userAgent, 'TOO_MANY_REQUESTS'); log('log', `Rate limited (429) while reporting ${event.clientIP}; URI: ${uri}`); cycleErrorCounts.blocked++; } else { @@ -143,7 +143,7 @@ const reportIP = async (event, hostname, endpoint, userAgent, country, cycleErro if (isImageRequest(event.clientRequestPath)) { cycleImageSkippedCount++; if (!wasImageRequestLogged(ip, reportedIPs)) { - logToCSV(event.rayName, ip, hostname, endpoint, null, 'Skipped - Image Request', country); + logToCSV(event.rayName, ip, country, hostname, endpoint, null, 'SKIPPED_IMAGE_REQUEST'); if (imageRequestLogged) continue; log('log', 'Skipping image requests in this cycle...'); @@ -153,7 +153,7 @@ const reportIP = async (event, hostname, endpoint, userAgent, country, cycleErro continue; } - const wasReported = await reportIP(event, hostname, endpoint, event.userAgent, country, cycleErrorCounts); + const wasReported = await reportIP(event, country, hostname, endpoint, event.userAgent, cycleErrorCounts); if (wasReported) { cycleReportedCount++; await new Promise(resolve => setTimeout(resolve, SUCCESS_COOLDOWN_MS)); diff --git a/package-lock.json b/package-lock.json index 487c324..a9bfbce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,26 +1,26 @@ { "name": "cf-waf-to-abuseipdb", - "version": "1.1.0", + "version": "1.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cf-waf-to-abuseipdb", - "version": "1.1.0", + "version": "1.1.1", "license": "MIT", "dependencies": { "axios": "^1.7.7", "dotenv": "^16.4.5" }, "devDependencies": { - "@eslint/js": "^9.9.1", + "@eslint/js": "^9.10.0", "globals": "^15.9.0" } }, "node_modules/@eslint/js": { - "version": "9.9.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.1.tgz", - "integrity": "sha512-xIDQRsfg5hNBqHz04H1R3scSVwmI+KUbqjsQKHKQ1DAUSaUjYPReZZmS/5PNiKu1fUvzDd6H7DEDKACSEhu+TQ==", + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", + "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", "dev": true, "license": "MIT", "engines": { @@ -78,9 +78,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.8", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", - "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", diff --git a/package.json b/package.json index 9757295..4047cb6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cf-waf-to-abuseipdb", - "version": "1.1.0", + "version": "1.1.1", "description": "A Node.js project that enables automatic reporting of incidents detected by Cloudflare WAF to the AbuseIPDB database.", "keywords": [ "abuseipdb", @@ -31,7 +31,7 @@ "dotenv": "^16.4.5" }, "devDependencies": { - "@eslint/js": "^9.9.1", + "@eslint/js": "^9.10.0", "globals": "^15.9.0" } } diff --git a/scripts/csv.js b/scripts/csv.js index b28e1a0..6c1787a 100644 --- a/scripts/csv.js +++ b/scripts/csv.js @@ -4,7 +4,7 @@ const log = require('./log.js'); const CSV_FILE_PATH = path.join(__dirname, '..', 'reported_ips.csv'); const MAX_CSV_SIZE_BYTES = 4 * 1024 * 1024; // 4 MB -const CSV_HEADER = 'Timestamp,RayID,IP,Hostname,Endpoint,User-Agent,Action,Country,SefinekAPI\n'; +const CSV_HEADER = 'Timestamp,CF RayID,IP,Country,Hostname,Endpoint,User-Agent,Action,SefinekAPI\n'; if (!fs.existsSync(CSV_FILE_PATH)) fs.writeFileSync(CSV_FILE_PATH, CSV_HEADER); @@ -21,9 +21,9 @@ const escapeCSVValue = value => { return value || ''; }; -const logToCSV = (rayId, ip, hostname, endpoint, useragent, action, country, sefinekAPI) => { +const logToCSV = (rayId, ip, country, hostname, endpoint, useragent, action, sefinekAPI) => { checkCSVSize(); - const logLine = `${new Date().toISOString()},${rayId},${ip},${hostname},${escapeCSVValue(endpoint)},${escapeCSVValue(useragent)},${action},${country || 'N/A'},${sefinekAPI || false}`; + const logLine = `${new Date().toISOString()},${rayId},${ip},${country || 'N/A'},${hostname},${escapeCSVValue(endpoint)},${escapeCSVValue(useragent)},${action},${sefinekAPI || false}`; fs.appendFileSync(CSV_FILE_PATH, logLine + '\n'); }; @@ -36,18 +36,18 @@ const readReportedIPs = () => { .slice(1) .filter(line => line.trim() !== '') .map(line => { - const parts = line.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g); + const parts = line.match(/(".*?"|[^",]+)(?=\s*,|\s*$)/g); if (!parts || parts.length < 9) return null; return { timestamp: new Date(parts[0]), rayId: parts[1], ip: parts[2], - hostname: parts[3], - endpoint: parts[4], - useragent: parts[5], - action: parts[6], - country: parts[7], + country: parts[3], + hostname: parts[4], + endpoint: parts[5], + useragent: parts[6].replace(/(^"|"$)/g, ''), + action: parts[7], sefinekAPI: parts[8] }; }) @@ -75,6 +75,6 @@ const updateSefinekAPIInCSV = (rayId, reportedToSefinekAPI) => { fs.writeFileSync(CSV_FILE_PATH, updatedLines.join('\n')); }; -const wasImageRequestLogged = (ip, reportedIPs) => reportedIPs.some(entry => entry.ip === ip && entry.action === 'Skipped - Image Request'); +const wasImageRequestLogged = (ip, reportedIPs) => reportedIPs.some(entry => entry.ip === ip && entry.action === 'SKIPPED_IMAGE_REQUEST'); module.exports = { logToCSV, readReportedIPs, updateSefinekAPIInCSV, wasImageRequestLogged }; \ No newline at end of file diff --git a/scripts/sefinekAPI.js b/scripts/sefinekAPI.js index 5018a9c..44ce824 100644 --- a/scripts/sefinekAPI.js +++ b/scripts/sefinekAPI.js @@ -5,8 +5,8 @@ const log = require('./log.js'); const SEFINEK_API_URL = process.env.SEFINEK_API_URL || `${process.env.NODE_ENV === 'production' ? 'https://api.sefinek.net' : 'http://127.0.0.1:4010'}/api/v2/cloudflare-waf-abuseipdb/post`; module.exports = async () => { - const reportedIPs = readReportedIPs().filter(ip => ip.action === 'Reported' && ip.sefinekAPI === 'false'); - if (reportedIPs.length === 0) return log('log', 'No IPs with action "Reported" and SefinekAPI false to send to Sefinek API'); + const reportedIPs = readReportedIPs().filter(ip => ip.action === 'REPORTED' && ip.sefinekAPI === 'false'); + if (reportedIPs.length === 0) return log('log', 'No IPs with `action Reported` and `SefinekAPI false` to send to Sefinek API'); const uniqueLogs = reportedIPs.reduce((acc, ip) => { if (acc.seen.has(ip.ip)) return acc;