`

Java Web中的入侵检测及简单实现

    博客分类:
  • Web
阅读更多
Java Web中的入侵检测及简单实现


一、简介

  在Java Web应用程中,特别是网站开发中,我们有时候需要为应用程序增加一个入侵检测程序来防止恶意刷新的功能,防止非法用户不断的往Web应用中重复发送数据。当然,入侵检测可以用很多方法实现,包括软件、硬件防火墙,入侵检测的策略也很多。在这里我们主要介绍的是Java Web应用程序中通过软件的方式实现简单的入侵检测及防御。

  该方法的实现原理很简单,就是用户访问Web系统时记录每个用户的信息,然后进行对照,并根据设定的策略(比如:1秒钟刷新页面10次)判断用户是否属于恶意刷新。

  我们的入侵检测程序应该放到所有Java Web程序的执行前,也即若发现用户是恶意刷新就不再继续执行Java Web中的其它部分内容,否则就会失去了意义。这就需要以插件的方式把入侵检测的程序置入Java Web应用中,使得每次用户访问Java Web,都先要到这个入侵检测程序中报一次到,符合规则才能放行。

  Java Web应用大致分为两种,一种纯JSP(+Java Bean)方式,一种是基于框架(如Struts、EasyJWeb等)的。第一种方式的Java Web可以通过Java Servlet中的Filter接口实现,也即实现一个Filter接口,在其doFilter方法中插入入侵检测程序,然后再web.xml中作简单的配置即可。在基于框架的Web应用中,由于所有应用都有一个入口,因此可以把入侵检测的程序直接插入框架入口引擎中,使框架本身支持入侵检测功能。当然,也可以通过实现Filter接口来实现。

  在EasyJWeb框架中,已经置入了简单入侵检测的程序,因此,这里我们以EasyJWeb框架为例,介绍具体的实现方法及源码,完整的代码可以在EasyJWeb源码中找到。

  在基于EasyJWeb的Java Web应用中(如http://www.easyjf.com/bbs/),默认情况下你只要连续刷新页面次数过多,即会弹出如下的错误:

  EasyJWeb框架友情提示!:-): 
  您对页面的刷新太快,请等待60秒后再刷新页面! 
  详细请查询http://www.easyjf.com


二、用户访问信息记录UserConnect.java类  

  这个类是一个简单的Java Bean,主要代表用户的信息,包括用户名、IP、第一次访问时间、最后登录时间、登录次数、用户状态等。全部代码如下:

package com.easyjf.web;
import java.util.Date;
/**
*
* <p>Title:用户验证信息</p>
* <p>Description:记录用户登录信息,判断用户登录情况</p>
* <p>Copyright: Copyright (c) 2006</p>
* <p>Company: www.easyjf.com</p>
* @author 蔡世友
* @version 1.0
*/
public class UserConnect {
private String userName;
private String ip;
private Date firstFailureTime;
private Date lastLoginTime;
private int failureTimes;//用户登录失败次数
private int status=0;//用户状态0表示正常,-1表示锁定
public int getFailureTimes() {
return failureTimes;
}
public void setFailureTimes(int failureTimes) {
this.failureTimes = failureTimes;
}
public Date getFirstFailureTime() {
return firstFailureTime;
}
public void setFirstFailureTime(Date firstFailureTime) {
this.firstFailureTime = firstFailureTime;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public Date getLastLoginTime() {
return lastLoginTime;
}
public void setLastLoginTime(Date lastLoginTime) {
this.lastLoginTime = lastLoginTime;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}


三、监控线程UserConnectManage.java类

  这是入侵检测的核心部分,主要实现具体的入侵检测、记录、判断用户信息、在线用户的刷新等功能,并提供其它应用程序使用本组件的调用接口。

package com.easyjf.web;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
/**
*
* <p>Title:用户入侵检测信息</p>
* <p>Description:用于判断用户刷新情况检查,默认为10秒钟之内连续连接10次为超时</p>
* <p>Copyright: Copyright (c) 2006</p>
* <p>Company: www.easyjf.com</p>
* @author 蔡世友
* @version 1.0
*/
public class UserConnectManage {
private static final Logger logger = (Logger) Logger.getLogger(UserConnectManage.class.getName());
private static int maxFailureTimes=10;//最大登录失败次数
private static long maxFailureInterval=10000;//毫秒,达到最大登录次数且在这个时间范围内
private static long waitInterval=60000;//失败后接受连接的等待时间,默认1分钟
private static int maxOnlineUser=200;//同时在线的最大数
private final static Map users=new HashMap();//使用ip+userName为key存放用户登录信息UserLoginAuth
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);
   //System.out.println("创建一个新线程!");
   checkThread.start();   
     }
  }

public void run() {  
  while(true)
  {
   if(parentThread.isAlive()){
   try{
   Thread.sleep(2000);
   int i=0;
   if(users.size()>maxOnlineUser)//当达到最大用户数时清除
   {
    synchronized(users){//执行删除操作
    Iterator it=users.keySet().iterator();
    Set set=new HashSet();
    Date now=new Date();
    while(it.hasNext())
    {
     Object key=it.next();
     UserConnect user=(UserConnect)users.get(key);
     if(now.getTime()-user.getFirstFailureTime().getTime()>maxFailureInterval)//删除超时的用户
     {      
      set.add(key);
      logger.info("删除了一个超时的连接"+i);
      i++;
     }
    }
    if(i<5)//如果删除少于5个,则强行删除1/2在线记录,牺牲性能的情况下保证内存
    {
     int num=maxOnlineUser/2;
     it=users.keySet().iterator();
     while(it.hasNext() && i<num)
     {      
      set.add(it.next());
      logger.info("删除了一个多余的连接"+i);
      i++;
     }
    }
    users.keySet().removeAll(set);
    }
   }
   
   }
   catch(Exception e)
   {
    e.printStackTrace();
   }
   
  }
   else
   {   
   break;
   }
  }
  logger.info("监视程序运行结束!"); 
}
}
//通过checkLoginValidate判断是否合法的登录连接,如果合法则继续,非法则执行
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)//把用户当前的访问信息加入到users容器中
{
  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);
}
//System.out.println(key+":"+auth.getFailureTimes()+":"+ret+":"+(now.getTime()-auth.getFirstFailureTime().getTime()));
return ret;
}
public static void reset(String ip,String userName)//重置用户信息

Date now=new Date(); 
String key=ip+":"+userName;
UserConnect auth=(UserConnect)users.get(key);
if(auth==null)//把用户当前的访问信息加入到users容器中
{
  auth=new UserConnect();
  auth.setIp(ip);
  auth.setUserName(userName);
  auth.setFailureTimes(0);
  auth.setFirstFailureTime(now);
  users.put(key,auth);

else
{
  auth.setFailureTimes(0);
  auth.setFirstFailureTime(now);
}
}
public static void remove(String ip,String userName)//删除用户在容器中的记录
{
String key=ip+":"+userName;
users.remove(key);
}
public static void clear()//清空容器中内容
{
if(!users.isEmpty())users.clear();
}
public static long getMaxFailureInterval() {
return maxFailureInterval;
}
public static void setMaxFailureInterval(long maxFailureInterval) {
UserConnectManage.maxFailureInterval = maxFailureInterval;
}
public static int getMaxFailureTimes() {
return maxFailureTimes;
}
public static void setMaxFailureTimes(int maxFailureTimes) {
UserConnectManage.maxFailureTimes = maxFailureTimes;
}
public static int getMaxOnlineUser() {
return maxOnlineUser;
}
public static void setMaxOnlineUser(int maxOnlineUser) {
UserConnectManage.maxOnlineUser = maxOnlineUser;
}
public static long getWaitInterval() {
return waitInterval;
}
public static void setWaitInterval(long waitInterval) {
UserConnectManage.waitInterval = waitInterval;
}



四、调用接口

  在需要进入侵检测判断的地方,直接使用UserConnectManage类中的checkLoginValidate方法即可。如EasyJWeb的核心Servlet 

com.easyjf.web.ActionServlet中调用UserConnectManage的代码:
   if(!UserConnectManage.checkLoginValidate(request.getRemoteAddr(),"guest"))
       {            
           info(request,response,new Exception("您对页面的刷新太快,请等待"+UserConnectManage.getWaitInterval()/1000+"秒后再刷新页面!"));
           return;
       }
   

五、总结

  当然,这里提供的方法只是一个简单的实现示例,由于上面的用户信息是直接保存在内存中,若并发用户很大的时候的代码的占用,可以考虑引入数据库来记录用户的访问信息,当然相应的执行效率肯定用降低。上面介绍的实现中,入侵检测判断的策略也只有用户访问次数及时间间隔两个元素,您还可以根据你的实现情况增加其它的检测元素。
分享到:
评论

相关推荐

    在Java Web中的入侵检测及简单实现

    在Java Web中的入侵检测及简单实现 java代码

    基于监督学习的web入侵检测系统源码.zip

    【毕业设计】基于监督学习的web入侵检测系统源码【毕业设计】基于监督学习的web入侵检测系统源码【毕业设计】基于监督学习的web入侵检测系统源码【毕业设计】基于监督学习的web入侵检测系统源码【毕业设计】基于监督...

    一种基于分布式网络入侵检测系统的实现.pdf

    【分布式网络入侵检测系统实现】是一种针对日益严重的网络安全问题而提出的解决方案。随着网络技术的快速发展和广泛应用,计算机系统和网络面临着各种安全威胁。该系统构建在现有的入侵检测技术之上,通过引入分布式...

    web版基于Java的海康摄像头SDK车牌抓拍功能二次开发(springboot+maven)

    本项目是一个用springboot+maven对海康sdk抓拍功能进行了二次开发,里面包含我自己的springboot项目、海康最新cs版sdk、最新web版sdk、项目的说明文档,可以实现摄像头的抓拍、预览、录像、对讲功能,亲测有效

    Java Web技术的安全与防范.pdf

    7. **服务器端安全**:服务器端的安全策略包括设置强密码,限制不必要的网络服务,使用防火墙和入侵检测系统,以及定期备份和恢复策略。 8. **持续监控与更新**:随着技术的不断发展,新的安全威胁不断出现,因此...

    基于网关的入侵检测系统设计.rar

    在这个项目中,Java被用来编写入侵检测系统的后端逻辑,包括数据包解析、规则匹配、报警机制等。 2. **数据包解析**:在入侵检测系统中,数据包解析是至关重要的一步。系统需要能够捕获网络中的数据包,解析其头部...

    关于Java Web应用程序安全技术研究.pdf

    从技术角度讲,安全策略包括加强服务器安全配置、定期进行安全漏洞扫描、使用防火墙和入侵检测系统等;管理方面,则涉及安全培训、风险评估和制定应急预案;法律方面,需要确保应用符合相关数据保护法规和标准。 综...

    基于网络的入侵检测系统源码.zip

    资源简介:基于网络的入侵检测系统源码本资源包名为“基于网络的入侵检测系统源码+数据集+详细文档(高分毕业设计)”,是一个综合性的IT安全项目,旨在提供可运行的源代码、相应的数据集和详细的文档资料。...

    毕业设计——基于监督学习的web入侵检测系统(0day收集器).zip

    毕业设计——基于监督学习的web入侵检测系统(0day收集器) ##机器学习方面 用的技术比较low,只是scikit-learn里面的svm用了一下,开始的时候用knn来着,当现在样本数量过万的时候发现knn的确吃力。 ##数据方面 ...

    用Java Web防范SQL注入攻击.pdf

    7. **应用防火墙与入侵检测系统**:配置专门针对SQL注入的防火墙规则,配合入侵检测系统(IDS)监控网络流量,及时发现并阻止SQL注入尝试。 8. **持续更新和修复**:保持应用程序、库和框架的更新,修复已知的安全...

    Java Web应用程序安全技术研究 (1).pdf

    8. **防火墙和入侵检测系统**:部署防火墙和入侵检测系统,阻止未经授权的访问和攻击。 总的来说,Java Web应用程序的安全不仅需要开发人员具备安全意识,还需要在整个开发周期中实施全面的安全策略。通过深入理解...

    基于Flume&spark&Flask的分布式实时日志分析与入侵检测系统.zip

    在本项目中,Spark 用于实时处理Flume收集的日志数据,通过其强大的数据处理能力,进行实时分析,如异常检测、模式识别等,以实现入侵检测功能。 3. **Java**:作为Spark的主要编程语言,Java 提供了丰富的API,...

    大华摄像头web3.0二次开发webplugin

    3. 报警管理:订阅并处理摄像头触发的报警事件,如移动检测、入侵报警等。 4. 用户管理:实现用户的登录、注册、权限控制等功能。 5. 系统设置:修改摄像头的工作模式、时间同步、网络配置等。 四、开发流程 1. ...

    harbinger:一个基于Spring MVCSecurity的Web应用程序入侵检测和防御框架

    一个基于Spring / 的Web应用程序入侵检测和防御框架。 甚至像恐惧事件的先兆一样,当先驱们仍在命运之前,在预兆即将到来之际,让天地一起向我们的气候和同胞展示。 -莎士比亚的哈姆雷特 Harbinger检测到您的Web...

    华为Web应用安全开发规范.doc

    该规范中介绍了入侵检测和防御的方法,包括入侵检测系统的架构和实现、入侵检测规则的设定、入侵防御策略等。这些方法旨在帮助开发者检测和防御Web应用中可能的入侵和攻击。 身份验证和授权 该规范中介绍了身份...

Global site tag (gtag.js) - Google Analytics