Skip to content

Commit aff8df6

Browse files
Java security interceptor
1 parent 21f8fce commit aff8df6

File tree

3 files changed

+382
-1
lines changed

3 files changed

+382
-1
lines changed

JavaSecurityInterceptor.java

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
package cgs.interceptor; // Your package name
2+
3+
import org.springframework.web.multipart.MultipartHttpServletRequest;
4+
import org.springframework.web.servlet.HandlerInterceptor;
5+
import org.springframework.web.servlet.ModelAndView;
6+
7+
import javax.servlet.http.HttpServletRequest;
8+
import javax.servlet.http.HttpServletResponse;
9+
import java.io.IOException;
10+
import java.util.Enumeration;
11+
import java.util.regex.Pattern;
12+
13+
/**
14+
* JavaSecurityInterceptor
15+
*
16+
* This interceptor validates HTTP requests to safeguard against security vulnerabilities
17+
* such as SQL Injection, Cross-Site Scripting (XSS), and malicious file uploads.
18+
* It performs validation checks on request parameters and file uploads, rejecting
19+
* any that appear to be malicious or invalid.
20+
*
21+
* Author: Deepak Kumar
22+
* Email: imchahardeepak@gmail.com
23+
* GitHub: https://github.com/imdeepakchahar/java-security-interceptor
24+
*/
25+
public class JavaSecurityInterceptor implements HandlerInterceptor {
26+
27+
// Pattern to detect SQL injection keywords in request parameters.
28+
private static final String SQL_INJECTION_PATTERN =
29+
"(?i).*\\b(select|insert|drop|update|delete|exec|union|create|alter|truncate|declare|--|\\/\\*|\\*\\/|;|where|having|limit|group)\\b.*";
30+
31+
// Pattern to detect dangerous characters such as <, >, ', ", %, and &.
32+
private static final String DANGEROUS_CHARACTERS_PATTERN = ".*[<>'\"%&].*";
33+
34+
// Pattern to ensure input is valid UTF-8 encoded.
35+
private static final String UTF8_PATTERN = "[\\u0000-\\u007F]+";
36+
37+
// Pattern to identify potential XSS payloads in the input.
38+
private static final String XSS_PATTERN = "<.*?>";
39+
40+
// Patterns to detect newline characters and null bytes in input.
41+
private static final String NEWLINE_PATTERN = "[\\r\\n]";
42+
private static final String NULL_BYTE_PATTERN = "%00";
43+
44+
// List of allowed file extensions for uploaded files.
45+
private static final String[] ALLOWED_FILE_EXTENSIONS = {"jpg", "jpeg", "png", "pdf", "docx"};
46+
47+
/**
48+
* Pre-handle method to validate HTTP requests before they reach the controller.
49+
*
50+
* @param request the HTTP request object
51+
* @param response the HTTP response object
52+
* @param handler the handler for the request
53+
* @return true if the request passes all validations, false otherwise
54+
* @throws Exception in case of any unexpected errors
55+
*/
56+
@Override
57+
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
58+
Enumeration<String> parameterNames = request.getParameterNames();
59+
60+
// Validate uploaded files for allowed extensions.
61+
if (!validateFileInput(request)) {
62+
response.sendError(400, "Invalid file type detected.");
63+
return false;
64+
}
65+
66+
// Iterate through all request parameters to validate their content.
67+
while (parameterNames.hasMoreElements()) {
68+
String paramName = parameterNames.nextElement();
69+
String paramValue = request.getParameter(paramName);
70+
71+
if (containsSQLInjection(paramValue)) {
72+
response.sendError(400, "SQL Injection detected in parameter: " + paramName);
73+
return false;
74+
}
75+
76+
if (containsDangerousCharacters(paramValue)) {
77+
response.sendError(400, "Dangerous characters detected in parameter: " + paramName);
78+
return false;
79+
}
80+
81+
if (containsXSS(paramValue)) {
82+
response.sendError(400, "XSS attack detected in parameter: " + paramName);
83+
return false;
84+
}
85+
86+
if (!isValidUTF8(paramValue)) {
87+
response.sendError(400, "Invalid UTF-8 encoding detected in parameter: " + paramName);
88+
return false;
89+
}
90+
91+
if (containsNewLine(paramValue) || containsNullByte(paramValue)) {
92+
response.sendError(400, "Invalid characters detected in parameter: " + paramName);
93+
return false;
94+
}
95+
}
96+
97+
return true;
98+
}
99+
100+
/**
101+
* Validates uploaded files for allowed extensions.
102+
*
103+
* @param request the HTTP request object
104+
* @return true if all files have valid extensions, false otherwise
105+
* @throws IOException in case of file handling errors
106+
*/
107+
private boolean validateFileInput(HttpServletRequest request) throws IOException {
108+
if (request instanceof MultipartHttpServletRequest) {
109+
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
110+
111+
java.util.Iterator<String> fileNames = multiRequest.getFileNames();
112+
while (fileNames.hasNext()) {
113+
String fileName = fileNames.next();
114+
String fileExtension = getFileExtension(fileName);
115+
116+
if (!isValidFileExtension(fileExtension)) {
117+
return false;
118+
}
119+
}
120+
}
121+
return true;
122+
}
123+
124+
/**
125+
* Extracts the file extension from a filename.
126+
*
127+
* @param filename the name of the file
128+
* @return the file extension, or an empty string if none is found
129+
*/
130+
private String getFileExtension(String filename) {
131+
if (filename == null || filename.isEmpty()) return "";
132+
int lastIndexOfDot = filename.lastIndexOf(".");
133+
return (lastIndexOfDot == -1) ? "" : filename.substring(lastIndexOfDot + 1);
134+
}
135+
136+
/**
137+
* Checks if the file extension is allowed.
138+
*
139+
* @param fileExtension the file extension to check
140+
* @return true if the extension is allowed, false otherwise
141+
*/
142+
private boolean isValidFileExtension(String fileExtension) {
143+
for (String allowedExtension : ALLOWED_FILE_EXTENSIONS) {
144+
if (allowedExtension.equalsIgnoreCase(fileExtension)) {
145+
return true;
146+
}
147+
}
148+
return false;
149+
}
150+
151+
/**
152+
* Validates input for SQL injection patterns.
153+
*
154+
* @param input the input string to validate
155+
* @return true if the input contains SQL injection patterns, false otherwise
156+
*/
157+
private boolean containsSQLInjection(String input) {
158+
return input != null && Pattern.compile(SQL_INJECTION_PATTERN).matcher(input).matches();
159+
}
160+
161+
/**
162+
* Checks if the input contains dangerous characters.
163+
*
164+
* @param input the input string to validate
165+
* @return true if dangerous characters are detected, false otherwise
166+
*/
167+
private boolean containsDangerousCharacters(String input) {
168+
return input != null && Pattern.compile(DANGEROUS_CHARACTERS_PATTERN).matcher(input).matches();
169+
}
170+
171+
/**
172+
* Validates input for Cross-Site Scripting (XSS) patterns.
173+
*
174+
* @param input the input string to validate
175+
* @return true if XSS patterns are detected, false otherwise
176+
*/
177+
private boolean containsXSS(String input) {
178+
return input != null && Pattern.compile(XSS_PATTERN).matcher(input).matches();
179+
}
180+
181+
/**
182+
* Checks if the input is valid UTF-8 encoded.
183+
*
184+
* @param input the input string to validate
185+
* @return true if the input is valid UTF-8 encoded, false otherwise
186+
*/
187+
private boolean isValidUTF8(String input) {
188+
return input == null || Pattern.compile(UTF8_PATTERN).matcher(input).matches();
189+
}
190+
191+
/**
192+
* Checks if the input contains newline characters.
193+
*
194+
* @param input the input string to validate
195+
* @return true if newline characters are detected, false otherwise
196+
*/
197+
private boolean containsNewLine(String input) {
198+
return input != null && Pattern.compile(NEWLINE_PATTERN).matcher(input).matches();
199+
}
200+
201+
/**
202+
* Checks if the input contains null byte characters.
203+
*
204+
* @param input the input string to validate
205+
* @return true if null byte characters are detected, false otherwise
206+
*/
207+
private boolean containsNullByte(String input) {
208+
return input != null && input.contains(NULL_BYTE_PATTERN);
209+
}
210+
211+
@Override
212+
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
213+
// This method can be used for additional processing after the controller handles the request.
214+
}
215+
216+
@Override
217+
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
218+
// This method can be used for cleanup activities after the request has been completed.
219+
}
220+
}

README.md

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,116 @@
1-
# java-security-interceptor
1+
2+
# Java Security Interceptor
3+
4+
This project is a Spring MVC-based Java application that implements a security interceptor to validate incoming HTTP requests and prevent common vulnerabilities such as SQL Injection, Cross-Site Scripting (XSS), and malicious file uploads.
5+
6+
## Features
7+
8+
- **SQL Injection Prevention**: Detects and blocks SQL injection patterns in request parameters.
9+
- **XSS Protection**: Filters out potential cross-site scripting attacks.
10+
- **File Upload Validation**: Allows only specific file types to be uploaded.
11+
- **Input Sanitization**: Rejects inputs with dangerous characters, invalid UTF-8 encoding, null bytes, or newline characters.
12+
13+
## Technologies Used
14+
15+
- **Spring Framework**: Core framework for building the application and managing interceptors.
16+
- **Java**: Programming language.
17+
- **Regex Patterns**: Used for input validation.
18+
19+
---
20+
21+
## Files Overview
22+
23+
### 1. **JavaSecurityInterceptor.java**
24+
This is the main interceptor that performs the following tasks:
25+
- Validates request parameters for SQL Injection, XSS, and other dangerous inputs.
26+
- Checks uploaded files for allowed extensions.
27+
- Rejects invalid or malicious requests.
28+
29+
#### Key Methods:
30+
- **`preHandle`**: Validates incoming requests before they reach the controller.
31+
- **`validateFileInput`**: Ensures uploaded files have valid extensions.
32+
- **`containsSQLInjection`**, **`containsXSS`**, etc.: Helper methods to check for specific vulnerabilities.
33+
34+
---
35+
36+
### 2. **WebConfig.java**
37+
This is the Spring configuration class that:
38+
- Registers the `JavaSecurityInterceptor` as a Spring Bean.
39+
- Adds the interceptor to the application's request handling pipeline to validate all incoming requests.
40+
41+
---
42+
43+
## Setup Instructions
44+
45+
### Prerequisites
46+
- Java 8 or higher
47+
- Maven 3.6+
48+
- Spring Framework 5+
49+
- An IDE (e.g., IntelliJ IDEA, Eclipse)
50+
51+
---
52+
53+
### Installation
54+
1. Clone this repository:
55+
```bash
56+
git clone https://github.com/imdeepakchahar/java-security-interceptor.git
57+
cd java-security-interceptor
58+
```
59+
60+
2. Import the project into your IDE.
61+
62+
3. Build the project using Maven:
63+
```bash
64+
mvn clean install
65+
```
66+
67+
4. Run the Spring Boot application:
68+
```bash
69+
mvn spring-boot:run
70+
```
71+
72+
---
73+
74+
## Usage
75+
76+
1. **Interceptor Behavior**:
77+
- The interceptor is applied to all request paths (`/**`).
78+
- Malicious requests are blocked with a `400 Bad Request` response.
79+
80+
2. **File Uploads**:
81+
- Allowed file extensions: `jpg`, `jpeg`, `png`, `pdf`, `docx`.
82+
83+
3. **Request Validation**:
84+
- SQL keywords, XSS payloads, dangerous characters, invalid UTF-8, and null bytes are blocked.
85+
86+
4. **Customization**:
87+
- Modify allowed file extensions in `ALLOWED_FILE_EXTENSIONS` in `JavaSecurityInterceptor.java`.
88+
- Update regex patterns to match your security requirements.
89+
90+
---
91+
92+
## Project Structure
93+
94+
```
95+
src/main/java/cgs/
96+
├── config/
97+
│ └── WebConfig.java # Spring configuration
98+
├── interceptor/
99+
│ └── JavaSecurityInterceptor.java # Security interceptor
100+
```
101+
102+
---
103+
104+
## Contact
105+
106+
**Author**: Deepak Kumar
107+
**Email**: [imchahardeepak@gmail.com](mailto:imchahardeepak@gmail.com)
108+
**GitHub**: [imdeepakchahar](https://github.com/imdeepakchahar)
109+
110+
Feel free to raise issues or contribute to this project!
111+
112+
---
113+
114+
## License
115+
116+
This project is open-source and available under the [MIT License](LICENSE).

WebConfig.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package cgs.config; // Your package name
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
6+
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
7+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
8+
9+
import cgs.interceptor.JavaSecurityInterceptor;
10+
11+
/**
12+
* WebConfig
13+
*
14+
* This configuration class sets up the Spring MVC web context.
15+
* It registers the JavaSecurityInterceptor to validate incoming requests for security risks.
16+
*
17+
* Author: Deepak Kumar
18+
* Email: imchahardeepak@gmail.com
19+
* GitHub: https://github.com/imdeepakchahar/java-security-interceptor
20+
*/
21+
@Configuration
22+
@EnableWebMvc
23+
public class WebConfig implements WebMvcConfigurer {
24+
25+
/**
26+
* Defines a JavaSecurityInterceptor bean.
27+
*
28+
* @return an instance of JavaSecurityInterceptor
29+
*/
30+
@Bean
31+
public JavaSecurityInterceptor javaSecurityInterceptor() {
32+
return new JavaSecurityInterceptor();
33+
}
34+
35+
/**
36+
* Adds the JavaSecurityInterceptor to the application's interceptor registry.
37+
* This ensures that all incoming requests are processed through the interceptor for validation.
38+
*
39+
* @param registry the registry to which the interceptor is added
40+
*/
41+
@Override
42+
public void addInterceptors(InterceptorRegistry registry) {
43+
registry.addInterceptor(javaSecurityInterceptor())
44+
.addPathPatterns("/**"); // Applies the interceptor to all request paths.
45+
}
46+
}

0 commit comments

Comments
 (0)