首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java Web 入侵偵測與防禦機制實作:基於 EasyJWeb 框架

     編輯:Java 程式設計入門

前言:為什麼需要 Web 入侵偵測?

在 Java Web 應用開發中,特別是公開網站,常面臨惡意刷新、暴力破解、資料重複提交等攻擊。入侵偵測系統(IDS)能即時識別異常存取模式,保護系統資源不被濫用。雖然有硬體/軟體防火牆方案,但在應用層實作輕量級偵測邏輯,能更精準針對業務場景防禦。

核心原理

實作邏輯直觀:記錄每位用戶的存取資訊(IP、用戶名、時間、頻率),根據預設策略(如:10 秒內連續請求超過 10 次)判定是否為惡意行為。偵測程式必須置於所有 Web 請求處理之前——若判定為惡意,直接攔截並回應錯誤,否則放行繼續執行。

整合方式

  • 純 JSP/Servlet 架構:實作 javax.servlet.Filter 介面,在 doFilter() 中植入偵測邏輯,於 web.xml 設定攔截路徑
  • 框架架構(Struts、EasyJWeb 等):利用框架唯一入口點,將偵測程式嵌入核心引擎,或同樣透過 Filter 實作

EasyJWeb 框架內建簡易入侵偵測,預設觸發時回應:
您對頁面的刷新太快,請等待60秒後再刷新頁面!

核心元件實作

1. 用戶連線資訊 Bean:UserConnect

記錄單一用戶的狀態資訊:

package com.easyjf.web;
import java.util.Date;

public class UserConnect {
    private String userName;
    private String ip;
    private Date firstFailureTime;  // 首次失敗時間
    private Date lastLoginTime;     // 最後登入時間
    private int failureTimes;       // 失敗/請求次數
    private int status = 0;         // 0=正常, -1=鎖定
    
    // Getter/Setter 方法...
}

2. 監控管理執行緒:UserConnectManage

核心偵測邏輯,採用單例模式管理所有用戶連線資訊,內含定期清理的監控執行緒:

package com.easyjf.web;
import java.util.*;
import org.apache.log4j.Logger;

public class UserConnectManage {
    private static final Logger logger = Logger.getLogger(UserConnectManage.class.getName());
    
    // 設定參數
    private static int maxFailureTimes = 10;      // 最大允許失敗次數
    private static long maxFailureInterval = 10000; // 時間窗口(毫秒):10秒
    private static long waitInterval = 60000;       // 鎖定等待時間:60秒
    private static int maxOnlineUser = 200;         // 最大同時在線用戶
    
    // 用戶資訊容器:key = "ip:username"
    private final static Map users = new HashMap();
    private static Thread checkThread = null;
    
    // 內部類別:定期清理逾時/過期連線記錄
    private static class CheckTimeOut implements Runnable {
        private Thread parentThread;
        
        public CheckTimeOut(Thread parentThread) {
            this.parentThread = parentThread;
            synchronized(this) {
                if (checkThread == null) {
                    checkThread = new Thread(this);
                    checkThread.start();
                }
            }
        }
        
        public void run() {
            while (true) {
                if (parentThread.isAlive()) {
                    try {
                        Thread.sleep(2000); // 每2秒檢查一次
                        
                        // 1. 移除超時記錄
                        // 2. 若在線用戶超過上限,強制清理舊記錄保護記憶體
                        // 詳細邏輯見原始碼...
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else break;
            }
            logger.info("監視程式結束!");
        }
    }
    
    // 核心驗證方法:判斷請求是否合法
    public static boolean checkLoginValidate(String ip, String userName) {
        boolean ret = true;
        Date now = new Date();
        String key = ip + ":" + userName;
        UserConnect auth = (UserConnect) users.get(key);
        
        if (auth == null) {
            // 首次請求,建立記錄
            auth = new UserConnect();
            auth.setIp(ip);
            auth.setUserName(userName);
            auth.setFailureTimes(0);
            auth.setFirstFailureTime(now);
            users.put(key, auth);
            if (checkThread == null) new CheckTimeOut(Thread.currentThread());
        } else {
            // 檢查是否超過頻率限制
            if (auth.getFailureTimes() > maxFailureTimes) {
                if ((now.getTime() - auth.getFirstFailureTime().getTime()) < maxFailureInterval) {
                    ret = false; // 在時間窗內超頻,拒絕
                    auth.setStatus(-1);
                } else if (auth.getStatus() == -1 && 
                           (now.getTime() - auth.getFirstFailureTime().getTime()) < (maxFailureInterval + waitInterval)) {
                    ret = false; // 鎖定期內,持續拒絕
                } else {
                    // 時間窗已過,重置計數器
                    auth.setFailureTimes(0);
                    auth.setFirstFailureTime(now);
                    auth.setStatus(0);
                }
            }
            // 請求計數 +1
            auth.setFailureTimes(auth.getFailureTimes() + 1);
        }
        return ret;
    }
    
    // 重置用戶狀態(如登入成功後)
    public static void reset(String ip, String userName) {
        // 實作細節...
    }
}

關鍵設計亮點

  1. 雙層防護:頻率限制(時間窗內請求數)+ 鎖定機制(冷卻期)
  2. 記憶體保護:監控執行緒定期清理逾時記錄,防止 Map 無限增長導致 OOM
  3. 靈活配置:閾值、時間窗、鎖定時長皆可依業務調整
  4. 非侵入式整合:透過 Filter 或框架擴充點植入,不影響既有業務邏輯

部署建議

  • 生產環境建議搭配分散式快取將用戶狀態外部化,支援叢集部署
  • 針對 API 介面可設定更嚴格的頻率限制
  • 記錄被攔截請求的詳細資訊(IP、UA、請求參數)供事後分析
  • 提供白名單機制避免誤傷合法爬蟲或合作夥伴整合

總結

應用層入侵偵測是 Web 安全防禦的重要一環。EasyJWeb 的實作展示了輕量級、可嵌入、可配置的偵測架構。實務上可根據業務風險等級,結合 WAF、行為分析、機器學習等進階手段,構建多層次防禦體系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved