Java Web intrusion detection and simple implementation

Source: Internet
Author: User
Tags date now

Prepared by easyjf open-source team Daxia

I. Introduction

In Java Web applications, especially website development, we sometimes need to add an intrusion detection program for applications to prevent malicious refreshing, prevent Unauthorized users from repeatedly sending data to Web applications. Of course, intrusion detection can be implemented in many ways, including software, hardware firewalls, and many intrusion detection policies. Here we mainly introduce Java Web applications to implement simple intrusion detection and defense through software.

The implementation principle of this method is very simple, that is, when a user accesses the web system, the information of each user is recorded, then compared, and according to the set policy (for example, refresh the page 10 times in one second) determines whether a user is maliciously refreshed.

Our intrusion detection program should be placed before the execution of all Java Web programs, that is, if you find that the user is maliciously refreshed, it will not continue to execute other content in Java Web, otherwise it will lose its meaning. This requires the intrusion detection program to be put into a Java Web application in the form of a plug-in, so that every time a user accesses the Java Web, the intrusion detection program must report it once, you can only pass the rules.

Java Web applications are roughly divided into two types: a pure JSP (+ Java Bean) method and a framework (such as Struts and easyjweb. The first method of Java Web can be implemented through the filter interface in Java Servlet, that is, to implement a filter interface, insert the intrusion detection program in its dofilter method, and then web. simple configuration in XML. In Framework-based Web applications, because all applications have an entry point, you can directly Insert the intrusion detection program into the framework entry engine so that the framework itself supports the intrusion detection function. Of course, you can also implement the filter interface.

Simple intrusion detection programs have been installed in the easyjweb framework. Therefore, here we take the easyjweb framework as an example to introduce the specific implementation methods and source code, complete code can be found in easyjweb source code.

In easyjweb-based Java Web applications (such as http://www.easyjf.com/bbs/), by default, you only need to refresh the page continuously too many times, the following error will pop up:

Easyjweb framework friendly reminder! :-):
You have refreshed the page too quickly. Please wait 60 seconds before refreshing the page!
Please query http://www.easyjf.com for details

Ii. userconnect. Java  

This class is a simple Java Bean that mainly represents user information, including the user name, IP address, first access time, Last Logon Time, number of logins, and user status. All

The Code is as follows:

Package com. easyjf. Web;

Import java. util. date;
/**
*
* <P> title: User Authentication Information </P>
* <P> Description: records user logon information and determines User Logon conditions. </P>
* <P> copyright: Copyright (c) 2006 </P>
* <P> company: www.easyjf.com </P>
* @ Author Cai shiyou
* @ Version 1.0
*/
Public class userconnect {
Private string username;
Private string IP;
Private date firstfailuretime;
Private date lastlogintime;
Private int failuretimes; // number of user logon failures
Private int status = 0; // user status 0 indicates normal,-1 indicates locked
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;
}

}

Iii. Monitoring thread userconnectmanage. Java class

This is the core part of intrusion detection. It mainly implements features such as intrusion detection, recording, determining user information, and refreshing online users, and provides call interfaces for other applications to use this component.

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: User Intrusion Detection Information </P>
* <P> Description: used to determine whether a user refresh is checked. The default value is 10 consecutive connections within 10 seconds. </P>
* <P> copyright: Copyright (c) 2006 </P>
* <P> company: www.easyjf.com </P>
* @ Author Cai shiyou
* @ Version 1.0
*/
Public class userconnectmanage {
Private Static final logger = (logger) Logger. getlogger (userconnectmanage. Class. getname ());
Private Static int maxfailuretimes = 10; // maximum number of Logon failures
Private Static long maxfailureinterval = 10000; // in milliseconds, the maximum number of logins is reached and within this time range
Private Static long waitinterval = 60000; // wait time for accepting connections after failure. The default value is 1 minute.
Private Static int maxonlineuser = 200; // maximum number of simultaneous online users
Private Final Static map users = new hashmap (); // use IP + username as the key to store user login information 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 ("Create a New thread! ");
Checkthread. Start ();
}
}
}
Public void run (){
While (true)
{
If (parentthread. isalive ()){
Try {
Thread. Sleep (2000 );
Int I = 0;
If (users. Size ()> maxonlineuser) // clear when the maximum number of users reaches
{
Synchronized (users) {// perform the delete operation
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) // delete a user with a deletion timeout
{
Set. Add (key );
Logger.info ("deleting a timeout connection" + I );
I ++;
}
}
If (I <5) // if less than five records are deleted, the 1/2 online records are forcibly deleted to ensure memory performance at the cost of performance.
{
Int num = maxonlineuser/2;
It = users. keyset (). iterator ();
While (it. hasnext () & I <num)
{
Set. Add (it. Next ());
Logger.info ("deleting a redundant connection" + I );
I ++;
}
}
Users. keyset (). removeall (SET );
}
}

}
Catch (exception E)
{
E. printstacktrace ();
}

}
Else
{
Break;
}
}
Logger.info ("the monitoring program is running! ");
}
}
// Use checkloginvalidate to determine whether a logon connection is valid. If the connection is valid, the connection is resumed. If the connection is invalid, the connection is executed.
Public static Boolean checkloginvalidate (string IP, string username) // only check the number of authentication failures
{
Boolean ret = true;
Date Now = new date ();
String key = IP + ":" + username;
Userconnect auth = (userconnect) users. Get (key );
If (auth = NULL) // Add the user's current access information to the users container
{
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 the time interval is specified, information about user connection rejection is returned.
If (now. gettime ()-auth. getfirstfailuretime (). gettime () <maxfailureinterval)
{
Ret = false;
Auth. setstatus (-1 );
}
Else if (Auth. getstatus () =-1 & (now. gettime ()-auth. getfirstfailuretime (). gettime () <(maxfailureinterval + waitinterval) // reset the counter
{
Ret = false;
}
Else
{
Auth. setfailuretimes (0 );
Auth. setfirstfailuretime (now );
Auth. setstatus (0 );
}

}
// The number of logins increases by 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) // reset user information
{
Date Now = new date ();
String key = IP + ":" + username;
Userconnect auth = (userconnect) users. Get (key );
If (auth = NULL) // Add the user's current access information to the users container
{
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) // delete a user's record in the container
{
String key = IP + ":" + username;
Users. Remove (key );
}
Public static void clear () // clear the content in the container
{
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;
}

Iv. Call Interfaces

You can directly use the checkloginvalidate method in the userconnectmanage class where you need to perform intrusion detection and judgment. For example, core servlet of easyjweb

Code for calling userconnectmanage in COM. easyjf. Web. actionservlet:
If (! Userconnectmanage. checkloginvalidate (request. getremoteaddr (), "guest "))
{
Info (request, response, new exception ("You have refreshed the page too fast, please wait" + userconnectmanage. getwaitinterval ()/1000 + "seconds

Then refresh the page! "));
Return;
}

  
    
V. Summary
Of course, the method provided here is just a simple implementation example. Because the above user information is directly stored in the memory, if the code is occupied when the number of concurrent users is large, you can consider introducing a database to record user access information. Of course, the execution efficiency must be reduced. In the above implementation, the intrusion detection and judgment policy only includes two elements: user access times and time interval. You can also add other detection elements based on your implementation.

Due to the limited level, the design has n unreasonable or need to be improved. please correct me!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.