NodeJS后端,用express实现Web防扫描

78 阅读1分钟

NodeJS后端,用express实现的Web服务器,通过记录访问频率和行为模式,识别潜在的恶意活动,从而实现Web服务器防扫描功能。

代码:

const express = require('express');
const app = express();
 
// 用于存储IP地址及其请求历史
const ipHistory = {};
 
// 防目录扫描中间件
function preventDirectoryScanning(req, res, next) {
  const ip = req.ip || req.connection.remoteAddress;
 
  // 初始化该IP的历史记录
  if (!ipHistory[ip]) {
    ipHistory[ip] = {
      requests: [],
      lastRequestTime: Date.now(),
      blockedUntil: 0,
    };
  }
 
  const history = ipHistory[ip];
 
  // 如果当前时间还在封禁时间内,则直接返回403
  if (Date.now() < history.blockedUntil) {
    console.log(`Blocked request from ${ip}: ${req.url}`);
    return res.status(403).send('Forbidden');
  }
 
  // 清除过期的请求记录
  history.requests = history.requests.filter(request => Date.now() - request.time < 60 * 1000); // 保留最近一分钟内的请求
 
  // 添加新的请求记录
  history.requests.push({
    time: Date.now(),
    url: req.url,
  });
 
  // 检查是否有大量对不存在资源的请求
  const recentRequestsCount = history.requests.length;
  const uniqueUrls = new Set(history.requests.map(r => r.url));
  const uniqueUrlCount = uniqueUrls.size;
 
  // 如果在短时间内有大量不同的URL请求,则可能是扫描行为
  if (recentRequestsCount > 20 && uniqueUrlCount / recentRequestsCount > 0.8) {
    // 封禁该IP一段时间
    history.blockedUntil = Date.now() + 5 * 60 * 1000; // 5分钟
    console.log(`Detected suspicious scanning activity from ${ip}. Blocking for 5 minutes.`);
    return res.status(403).send('Forbidden');
  }
 
  next();  // 继续处理请求
}
 
// 使用中间件
app.use(preventDirectoryScanning);
 
// 定义路由
app.get('/', (req, res) => {
  res.send('Hello World!');
});
 
// 启动Web服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

代码说明:

ipHistory用于存储每个IP地址的请求历史。 中间件preventDirectoryScanning会检查来自特定IP的所有请求,并记录它们。 如果某个IP在短时间内尝试访问多个不同的URL(这里定义为超过20个不同URL),并且这些URL大多是不存在的资源(假设大部分请求都是404错误),那么这个IP将被暂时封禁5分钟。 这样就实现了Web服务器防扫描功能。

原文链接:www.fairysoftware.com/tips/202410…