UNPKG

route-eyes

Version:

Express middleware to detect and optionally block suspicious or malicious route access attempts.

220 lines (206 loc) 6.82 kB
const fs = require("fs"); const path = require("path"); const paths = [ "/admin.php", "/admin/admin.php", "/admin/function.php", "/admin/index.php", "/adminfuns.php", "/akc.php", "/al.php", "/alfa.php", "/as.php", "/asasx.php", "/assets/images/doc.php", "/atomlib.php", "/auth.php", "/autoload_classmap.php", "/autoload_classmap/function.php", "/b.php", "/blog/fw.php", "/bugz.php", "/byp.php", "/cc.php", "/chosen.php", "/class.php", "/classwithtostring.php", "/composer.php", "/css.php", "/dropdown.php", "/edit.php", "/f35.php", "/file.php", "/file2.php", "/filemanager.php", "/files/index.php", "/fix.php", "/fm.php", "/flower.php", "/fox.php", "/function/function.php", "/g.php", "/gecko.php", "/gel4y.php", "/gelay.php", "/gg.php", "/goat.php", "/goods.php", "/h.php", "/images/admin.php", "/images/class-config.php", "/inc.php", "/index.bak.php", "/index/function.php", "/info.php", "/infos.php", "/ioxi-o.php", "/k.php", "/m.php", "/mar.php", "/mini", "/mini.php", "/mm.php", "/ms-edit.php", "/ms-themes.php", "/options-general.php", "/options-reading.php", "/options-writing.php", "/ova.php", "/pages.php", "/php.php", "/php8.php", "/pinfo.php", "/radio.php", "/robots.php", "/rt.php", "/s.php", "/setup.php", "/simple.php", "/sts.php", "/system_log.php", "/test1.php", "/themes/zMousse/otuz1.php", "/tinyfilemanager.php", "/ty.php", "/users.php", "/w.php", "/wp-aa.php", "/wp-admin/", "/wp-admin/admin.php", "/wp-admin/classwithtostring.php", "/wp-admin/css/colors/blue/index.php", "/wp-admin/css/colors/ectoplasm/about.php", "/wp-admin/css/colors/light/wp-login.php", "/wp-admin/images/moon.php", "/wp-admin/includes/colour.php", "/wp-admin/includes/header.php", "/wp-admin/includes/index.php", "/wp-admin/install.php", "/wp-admin/js/autoload_classmap.php", "/wp-admin/js/index.php", "/wp-admin/js/widgets/cloud.php", "/wp-admin/js/widgets/index.php", "/wp-admin/mah.php", "/wp-admin/maint/about.php", "/wp-admin/network/network.php", "/wp-admin/wp-admins.php", "/wp-admin/wp-login.php", "/wp-admin/wp.php", "/wp-api.php", "/wp-comments.php", "/wp-content/1.php", "/wp-content/about.php", "/wp-content/autoload_classmap.php", "/wp-content/classwithtostring.php", "/wp-content/click.php", "/wp-content/index.php", "/wp-content/languages/autoload_classmap.php", "/wp-content/plugin.php", "/wp-content/plugins/WordPressCore/include.php", "/wp-content/plugins/autoload_classmap.php", "/wp-content/plugins/ioxi/ioxi/dropdown.php", "/wp-content/plugins/pwnd/as.php", "/wp-content/plugins/revslider/includes/external/page/index.php", "/wp-content/plugins/up/main.php", "/wp-content/themes/admin.php", "/wp-content/uploads/chosen.php", "/wp-content/uploads/de_fb_uploads/b.php", "/wp-content/uploads/json.php", "/wp-content/wp.php", "/wp-error.php", "/wp-includes/ALFA_DATA/alfacgiapi/perl.alfa", "/wp-includes/IXR/autoload_classmap.php", "/wp-includes/IXR/chosen.php", "/wp-includes/PHPMailer/file.php", "/wp-includes/SimplePie/chosen.php", "/wp-includes/about.php", "/wp-includes/blocks/about.php", "/wp-includes/blocks/calendar/index.php", "/wp-includes/certificates/chosen.php", "/wp-includes/css/autoload_classmap.php", "/wp-includes/fonts/admin.php", "/wp-includes/fonts/autoload_classmap.php", "/wp-includes/fonts/index.php", "/wp-includes/html-api/about.php", "/wp-includes/js/tinymce/langs/about.php", "/wp-includes/rest-api/index.php", "/wp-includes/style-engine/autoload_classmap.php", "/wp-includes/widgets/autoload_classmap.php", "/wp-includes/wp-class.php", "/wp-includes/wp_class_datlib.php", "/wp-l0gin.php" ]; function routeEyes({ block = false, onDetect, log = true, banFile = "banned_ips.json" } = {}) { const banFilePath = path.resolve(banFile); // 벤 리스트 불러오기 let bannedIps = []; if (fs.existsSync(banFilePath)) { try { bannedIps = JSON.parse(fs.readFileSync(banFilePath, "utf-8")); } catch (err) { console.error("[route-eyes] Failed to read ban file:", err); bannedIps = []; } } // IP 벤 저장 함수 function saveBanList() { try { fs.writeFileSync(banFilePath, JSON.stringify(bannedIps, null, 2)); } catch (err) { console.error("[route-eyes] Failed to save ban file:", err); } } return function (req, res, next) { // 1. 이미 벤된 IP인지 확인 if (bannedIps.includes(req.ip)) { if (log) { console.warn(`[route-eyes] Blocked banned IP: ${req.ip}`); } return res.status(403).send("Forbidden"); } // 2. 경로 매칭 확인 const matched = paths.some(p => { if (typeof p === "string") return req.path === p; if (p instanceof RegExp) return p.test(req.path); return false; }); if (matched) { if (log) { console.warn(`[route-eyes] Detected suspicious access: ${req.path} from IP ${req.ip}`); } if (typeof onDetect === "function") { onDetect(req, res); } // 3. 벤 IP 목록에 추가 if (!bannedIps.includes(req.ip)) { bannedIps.push(req.ip); saveBanList(); } if (block) { return res.status(403).send("Forbidden"); } } next(); }; } module.exports = routeEyes;