本文目录导读:

我来为您提供一个完整的Java WAF(Web应用防火墙)实现案例,包含SQL注入、XSS、CSRF防护等功能。
项目结构
java-waf/
├── src/main/java/com/waf/
│ ├── filter/
│ │ └── WafFilter.java
│ ├── rule/
│ │ ├── SqlInjectionRule.java
│ │ ├── XssRule.java
│ │ ├── CsrfRule.java
│ │ └── RuleEngine.java
│ ├── config/
│ │ └── WafConfig.java
│ └── util/
│ └── SecurityUtil.java
└── src/main/resources/
└── waf-rules.xml
核心实现
1 WAF过滤器
package com.waf.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.logging.Logger;
@WebFilter("/*")
public class WafFilter implements Filter {
private static final Logger LOG = Logger.getLogger(WafFilter.class.getName());
private RuleEngine ruleEngine;
private WafConfig config;
@Override
public void init(FilterConfig filterConfig) {
this.ruleEngine = new RuleEngine();
this.config = WafConfig.loadConfig();
LOG.info("WAF Filter initialized");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) {
chain.doFilter(request, response);
return;
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
try {
// 1. 请求验证
if (!validateRequest(httpRequest, httpResponse)) {
return;
}
// 2. 包装请求(用于请求清洗)
WafRequestWrapper wrappedRequest = new WafRequestWrapper(httpRequest);
// 3. 继续处理
chain.doFilter(wrappedRequest, response);
} catch (Exception e) {
LOG.severe("WAF processing error: " + e.getMessage());
httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
private boolean validateRequest(HttpServletRequest request,
HttpServletResponse response) throws IOException {
// 获取请求参数
Map<String, String[]> parameters = request.getParameterMap();
String requestUri = request.getRequestURI();
String method = request.getMethod();
// 1. SQL注入检测
if (config.isSqlInjectionEnabled() &&
ruleEngine.checkSqlInjection(parameters)) {
handleAttack("SQL Injection", request, response);
return false;
}
// 2. XSS检测
if (config.isXssEnabled() &&
ruleEngine.checkXss(parameters)) {
handleAttack("XSS", request, response);
return false;
}
// 3. CSRF检测
if (config.isCsrfEnabled() &&
!ruleEngine.checkCsrf(request)) {
handleAttack("CSRF", request, response);
return false;
}
// 4. 路径遍历检测
if (config.isPathTraversalEnabled() &&
ruleEngine.checkPathTraversal(requestUri)) {
handleAttack("Path Traversal", request, response);
return false;
}
// 5. 文件上传检测
if (config.isFileUploadEnabled() &&
"POST".equalsIgnoreCase(method) &&
request.getContentType() != null &&
request.getContentType().contains("multipart/form-data")) {
if (!ruleEngine.checkFileUpload(request)) {
handleAttack("Malicious File Upload", request, response);
return false;
}
}
return true;
}
private void handleAttack(String attackType, HttpServletRequest request,
HttpServletResponse response) throws IOException {
LOG.warning(String.format("Blocked %s attack from IP: %s, URI: %s",
attackType,
request.getRemoteAddr(),
request.getRequestURI()));
// 记录攻击日志
logAttack(attackType, request);
// 返回403
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.getWriter().write("Request blocked by WAF");
}
private void logAttack(String attackType, HttpServletRequest request) {
AttackLog log = new AttackLog();
log.setAttackType(attackType);
log.setIp(request.getRemoteAddr());
log.setUri(request.getRequestURI());
log.setUserAgent(request.getHeader("User-Agent"));
log.setTimestamp(new Date());
log.setParameters(request.getParameterMap());
// 保存到数据库或文件
AttackLogger.save(log);
}
@Override
public void destroy() {
LOG.info("WAF Filter destroyed");
}
}
2 请求包装器
package com.waf.filter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.*;
public class WafRequestWrapper extends HttpServletRequestWrapper {
private Map<String, String[]> sanitizedParameters;
public WafRequestWrapper(HttpServletRequest request) {
super(request);
this.sanitizedParameters = sanitizeParameters(request.getParameterMap());
}
@Override
public String getParameter(String name) {
String[] values = sanitizedParameters.get(name);
return values != null && values.length > 0 ? values[0] : null;
}
@Override
public Map<String, String[]> getParameterMap() {
return sanitizedParameters;
}
@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(sanitizedParameters.keySet());
}
@Override
public String[] getParameterValues(String name) {
return sanitizedParameters.get(name);
}
private Map<String, String[]> sanitizeParameters(Map<String, String[]> parameters) {
Map<String, String[]> sanitized = new HashMap<>();
for (Map.Entry<String, String[]> entry : parameters.entrySet()) {
String[] sanitizedValues = new String[entry.getValue().length];
for (int i = 0; i < entry.getValue().length; i++) {
sanitizedValues[i] = SecurityUtil.sanitizeInput(entry.getValue()[i]);
}
sanitized.put(entry.getKey(), sanitizedValues);
}
return sanitized;
}
}
3 规则引擎
package com.waf.rule;
import java.util.*;
import java.util.regex.Pattern;
public class RuleEngine {
private SqlInjectionRule sqlInjectionRule;
private XssRule xssRule;
private CsrfRule csrfRule;
public RuleEngine() {
this.sqlInjectionRule = new SqlInjectionRule();
this.xssRule = new XssRule();
this.csrfRule = new CsrfRule();
}
public boolean checkSqlInjection(Map<String, String[]> parameters) {
return sqlInjectionRule.check(parameters);
}
public boolean checkXss(Map<String, String[]> parameters) {
return xssRule.check(parameters);
}
public boolean checkCsrf(HttpServletRequest request) {
return csrfRule.check(request);
}
public boolean checkPathTraversal(String uri) {
// 检查路径遍历
String pattern = "(\\.\\./|\\.\\.\\\\)|(\\%2e\\%2e/)";
return Pattern.compile(pattern, Pattern.CASE_INSENSITIVE).matcher(uri).find();
}
public boolean checkFileUpload(HttpServletRequest request) {
// 文件上传验证
try {
String contentType = request.getContentType();
if (contentType != null && contentType.contains("multipart/form-data")) {
// 检查文件大小
long contentLength = request.getContentLengthLong();
if (contentLength > 10 * 1024 * 1024) { // 10MB limit
return false;
}
// 检查文件名
String fileName = extractFileName(request);
if (fileName != null) {
// 验证文件扩展名
String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
Set<String> allowedExtensions = new HashSet<>(Arrays.asList(
"jpg", "jpeg", "png", "gif", "pdf", "doc", "docx", "txt"
));
if (!allowedExtensions.contains(extension.toLowerCase())) {
return false;
}
// 检查文件名中的路径遍历
if (fileName.contains("..") || fileName.contains("/") || fileName.contains("\\")) {
return false;
}
}
}
} catch (Exception e) {
return false;
}
return true;
}
private String extractFileName(HttpServletRequest request) {
// 从multipart请求中提取文件名
String header = request.getHeader("Content-Disposition");
if (header != null && header.contains("filename=")) {
String fileName = header.substring(header.indexOf("filename=") + 9);
if (fileName.startsWith("\"")) {
fileName = fileName.substring(1);
}
int endIndex = fileName.indexOf("\"");
if (endIndex > 0) {
fileName = fileName.substring(0, endIndex);
}
return fileName.trim();
}
return null;
}
}
4 SQL注入检测规则
package com.waf.rule;
import java.util.*;
import java.util.regex.Pattern;
public class SqlInjectionRule {
// SQL注入关键词
private static final String[] SQL_KEYWORDS = {
"SELECT", "INSERT", "UPDATE", "DELETE", "DROP", "UNION",
"EXEC", "EXECUTE", "ALTER", "CREATE", "TRUNCATE", "LOAD",
"INTO", "OUTFILE", "DUMPFILE", "SLEEP", "BENCHMARK",
"OR", "AND", "NOT", "NULL", "LIKE", "BETWEEN", "IN"
};
// SQL注入模式
private static final Pattern[] SQL_PATTERNS = {
Pattern.compile("'.*?OR.*?'.*?'.*?=.*?'"),
Pattern.compile("'.*?AND.*?'.*?'.*?=.*?'"),
Pattern.compile("--.*?$"),
Pattern.compile("/\\*.*?\\*/"),
Pattern.compile("UNION.*?SELECT", Pattern.CASE_INSENSITIVE),
Pattern.compile("SELECT.*?FROM", Pattern.CASE_INSENSITIVE),
Pattern.compile("INSERT.*?INTO", Pattern.CASE_INSENSITIVE),
Pattern.compile("DELETE.*?FROM", Pattern.CASE_INSENSITIVE),
Pattern.compile("DROP.*?(TABLE|DATABASE)", Pattern.CASE_INSENSITIVE),
Pattern.compile("EXEC(UTE)?\\s*\\(?", Pattern.CASE_INSENSITIVE),
Pattern.compile("SLEEP\\s*\\(", Pattern.CASE_INSENSITIVE),
Pattern.compile("BENCHMARK\\s*\\(", Pattern.CASE_INSENSITIVE),
Pattern.compile("WAITFOR\\s+DELAY", Pattern.CASE_INSENSITIVE),
Pattern.compile("0x[0-9a-fA-F]+"), // 十六进制编码
Pattern.compile("CHAR\\s*\\(\\d+\\)", Pattern.CASE_INSENSITIVE)
};
public boolean check(Map<String, String[]> parameters) {
if (parameters == null || parameters.isEmpty()) {
return false;
}
for (Map.Entry<String, String[]> entry : parameters.entrySet()) {
String paramName = entry.getKey();
String[] paramValues = entry.getValue();
// 排除非用户输入参数
if (isExcludedParameter(paramName)) {
continue;
}
for (String value : paramValues) {
if (value != null && containsSqlInjection(value)) {
return true;
}
}
}
return false;
}
private boolean containsSqlInjection(String input) {
// 1. 检查SQL关键词
String upperInput = input.toUpperCase();
for (String keyword : SQL_KEYWORDS) {
// 检查完整的关键词(需要前后有空格或特殊字符)
Pattern keywordPattern = Pattern.compile(
"\\b" + Pattern.quote(keyword) + "\\b",
Pattern.CASE_INSENSITIVE
);
if (keywordPattern.matcher(input).find()) {
// 进一步验证上下文
if (hasSqlContext(input, keyword)) {
return true;
}
}
}
// 2. 检查SQL注入模式
for (Pattern pattern : SQL_PATTERNS) {
if (pattern.matcher(input).find()) {
return true;
}
}
// 3. 检查常见的SQL注入特征
if (hasSqlInjectionFeatures(input)) {
return true;
}
return false;
}
private boolean hasSqlContext(String input, String keyword) {
// 检查是否有SQL语句的上下文环境
String[] sqlOperators = {"=", "'", "\"", "--", "/*", "*/"};
for (String operator : sqlOperators) {
if (input.contains(operator)) {
return true;
}
}
// 检查是否有多个关键词组合
int keywordCount = 0;
String upperInput = input.toUpperCase();
for (String k : SQL_KEYWORDS) {
if (upperInput.contains(k)) {
keywordCount++;
}
}
return keywordCount >= 2;
}
private boolean hasSqlInjectionFeatures(String input) {
// 检查编码混淆
if (input.contains("%27") || // '
input.contains("%22") || // "
input.contains("%3B")) { // ;
return true;
}
// 检查Unicode混淆
if (input.contains("\\u0027") || // '
input.contains("\\u0022")) { // "
return true;
}
// 检查注释符号
if (input.contains("#") && input.length() > 2) {
return true;
}
// 检查布尔注入
if (Pattern.compile("\\d+\\s*=\\s*\\d+").matcher(input).find() &&
(input.contains("'") || input.contains("\""))) {
return true;
}
return false;
}
private boolean isExcludedParameter(String paramName) {
// 排除系统参数或已知安全的参数
Set<String> excludedParams = new HashSet<>(Arrays.asList(
"_", "callback", "_dc", "page", "limit", "start"
));
return excludedParams.contains(paramName.toLowerCase());
}
}
5 XSS检测规则
package com.waf.rule;
import java.util.*;
import java.util.regex.Pattern;
public class XssRule {
// XSS模式列表
private static final Pattern[] XSS_PATTERNS = {
// 基本脚本标签
Pattern.compile("<script[^>]*>.*?</script>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL),
Pattern.compile("<script[^>]*>", Pattern.CASE_INSENSITIVE),
// JavaScript事件处理器
Pattern.compile("on\\w+\\s*=", Pattern.CASE_INSENSITIVE),
Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE),
Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE),
Pattern.compile("livescript:", Pattern.CASE_INSENSITIVE),
// HTML标签属性
Pattern.compile("<embed[^>]*>", Pattern.CASE_INSENSITIVE),
Pattern.compile("<object[^>]*>", Pattern.CASE_INSENSITIVE),
Pattern.compile("<applet[^>]*>", Pattern.CASE_INSENSITIVE),
Pattern.compile("<iframe[^>]*>", Pattern.CASE_INSENSITIVE),
Pattern.compile("<frame[^>]*>", Pattern.CASE_INSENSITIVE),
Pattern.compile("<form[^>]*>", Pattern.CASE_INSENSITIVE),
// CSS表达式
Pattern.compile("expression\\s*\\(", Pattern.CASE_INSENSITIVE),
Pattern.compile("-moz-binding", Pattern.CASE_INSENSITIVE),
Pattern.compile("behavior\\s*:", Pattern.CASE_INSENSITIVE),
// 数据URI
Pattern.compile("data\\s*:", Pattern.CASE_INSENSITIVE),
// SVG事件
Pattern.compile("<svg[^>]*>", Pattern.CASE_INSENSITIVE),
Pattern.compile("onload\\s*=", Pattern.CASE_INSENSITIVE),
Pattern.compile("onerror\\s*=", Pattern.CASE_INSENSITIVE),
// HTML编码绕过
Pattern.compile("&#\\d+;"),
Pattern.compile("&#x[0-9a-fA-F]+;"),
Pattern.compile("\\&[a-zA-Z]+\\;"),
// 其他攻击向量
Pattern.compile("<[^>]*style\\s*=\\s*['\"].*?expression.*?['\"]",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL),
Pattern.compile("document\\.\\w+", Pattern.CASE_INSENSITIVE),
Pattern.compile("window\\.\\w+", Pattern.CASE_INSENSITIVE),
Pattern.compile("eval\\s*\\(", Pattern.CASE_INSENSITIVE),
Pattern.compile("alert\\s*\\(", Pattern.CASE_INSENSITIVE),
Pattern.compile("confirm\\s*\\(", Pattern.CASE_INSENSITIVE),
Pattern.compile("prompt\\s*\\(", Pattern.CASE_INSENSITIVE),
};
public boolean check(Map<String, String[]> parameters) {
if (parameters == null || parameters.isEmpty()) {
return false;
}
for (Map.Entry<String, String[]> entry : parameters.entrySet()) {
for (String value : entry.getValue()) {
if (value != null && containsXss(value)) {
return true;
}
}
}
return false;
}
private boolean containsXss(String input) {
// 1. 检查XSS模式
for (Pattern pattern : XSS_PATTERNS) {
if (pattern.matcher(input).find()) {
return true;
}
}
// 2. 检查嵌套和混淆
if (hasObfuscatedXss(input)) {
return true;
}
// 3. 检查字符编码绕过
if (hasEncodedXss(input)) {
return true;
}
return false;
}
private boolean hasObfuscatedXss(String input) {
// 检查嵌套标签
if (countOccurrences(input, '<') > 2 &&
countOccurrences(input, '>') > 2) {
return true;
}
// 检查HTML实体编码
if (input.contains("<") || input.contains(">") ||
input.contains(""") || input.contains("'")) {
// 需要解码后再次检查
String decoded = SecurityUtil.decodeHtmlEntities(input);
for (Pattern pattern : XSS_PATTERNS) {
if (pattern.matcher(decoded).find()) {
return true;
}
}
}
return false;
}
private boolean hasEncodedXss(String input) {
// 检查Unicode编码
if (input.contains("\\u003c") || // <
input.contains("\\u003e")) { // >
return true;
}
// 检查Base64编码
if (input.length() > 10 && isBase64(input)) {
try {
String decoded = new String(Base64.getDecoder().decode(input));
for (Pattern pattern : XSS_PATTERNS) {
if (pattern.matcher(decoded).find()) {
return true;
}
}
} catch (Exception e) {
// 不是有效的Base64编码
}
}
return false;
}
private int countOccurrences(String str, char ch) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == ch) {
count++;
}
}
return count;
}
private boolean isBase64(String str) {
String base64Pattern = "^[A-Za-z0-9+/]+=*$";
return Pattern.compile(base64Pattern).matcher(str).matches();
}
}
6 CSRF防护规则
package com.waf.rule;
import javax.servlet.http.HttpServletRequest;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.HashSet;
import java.util.Set;
public class CsrfRule {
private static final String CSRF_TOKEN_HEADER = "X-CSRF-Token";
private static final String CSRF_TOKEN_PARAM = "_csrf";
private static final Set<String> SAFE_METHODS = new HashSet<String>() {{
add("GET");
add("HEAD");
add("OPTIONS");
add("TRACE");
}};
private SecureRandom random = new SecureRandom();
public boolean check(HttpServletRequest request) {
String method = request.getMethod().toUpperCase();
// GET请求不检查CSRF
if (SAFE_METHODS.contains(method)) {
return true;
}
// 从session获取token
String sessionToken = (String) request.getSession().getAttribute("csrf_token");
if (sessionToken == null) {
// 生成新token
sessionToken = generateToken();
request.getSession().setAttribute("csrf_token", sessionToken);
return true; // 首次访问不验证
}
// 从请求中获取token
String requestToken = request.getHeader(CSRF_TOKEN_HEADER);
if (requestToken == null) {
requestToken = request.getParameter(CSRF_TOKEN_PARAM);
}
// 验证token
if (requestToken == null || !sessionToken.equals(requestToken)) {
return false;
}
return true;
}
public String generateToken() {
byte[] tokenBytes = new byte[32];
random.nextBytes(tokenBytes);
return Base64.getUrlEncoder().withoutPadding().encodeToString(tokenBytes);
}
// 验证来源
public boolean checkReferer(HttpServletRequest request) {
String referer = request.getHeader("Referer");
if (referer == null) {
return false; // 没有Referer的请求可能是CSRF
}
String serverHost = request.getServerName();
int serverPort = request.getServerPort();
// 构建期望的Referer模式
String expectedReferer = String.format("http://%s:%d", serverHost, serverPort);
if (request.isSecure()) {
expectedReferer = String.format("https://%s:%d", serverHost, serverPort);
}
return referer.startsWith(expectedReferer);
}
// 检查SameSite Cookie
public boolean checkSameSiteCookie(HttpServletRequest request) {
String[] cookies = request.getCookies();
if (cookies != null) {
for (String cookie : cookies) {
// 检查cookie是否设置了SameSite属性
if (cookie.toLowerCase().contains("samesite")) {
return true;
}
}
}
return false;
}
}
7 安全工具类
package com.waf.util;
import org.owasp.encoder.Encode;
import java.util.regex.Pattern;
public class SecurityUtil {
// 输入清洗
public static String sanitizeInput(String input) {
if (input == null || input.isEmpty()) {
return input;
}
// 1. 去除空字符
input = input.replaceAll("\\x00", "");
// 2. HTML实体编码
input = Encode.forHtml(input);
// 3. 转义特殊字符
input = input.replace("&", "&")
.replace("<", "<")
.replace(">", ">")
.replace("\"", """)
.replace("'", "'")
.replace("/", "/");
// 4. 去除控制字符
input = input.replaceAll("[\\p{Cntrl}&&[^\\r\\n\\t]]", "");
// 5. 限制长度
if (input.length() > 1000) {
input = input.substring(0, 1000);
}
return input;
}
// URL安全验证
public static boolean isValidUrl(String url) {
if (url == null || url.isEmpty()) {
return false;
}
// URL模式
String urlPattern = "^(https?|ftp)://[\\w.-]+(:\\d+)?(/[\\w./%-]*)?(\\?[\\w&=-]*)?(#\\w*)?$";
return Pattern.compile(urlPattern, Pattern.CASE_INSENSITIVE).matcher(url).matches();
}
// IP地址验证
public static boolean isValidIp(String ip) {
if (ip == null || ip.isEmpty()) {
return false;
}
// IPv4模式
String ipv4Pattern = "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$";
// IPv6模式
String ipv6Pattern = "^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$";
return Pattern.compile(ipv4Pattern).matcher(ip).matches() ||
Pattern.compile(ipv6Pattern).matcher(ip).matches();
}
// HTML实体解码
public static String decodeHtmlEntities(String input) {
if (input == null || input.isEmpty()) {
return input;
}
input = input.replace("<", "<")
.replace(">", ">")
.replace("&", "&")
.replace(""", "\"")
.replace("'", "'")
.replace("/", "/");
// 解码数字实体
Pattern numericEntityPattern = Pattern.compile("&#(\\d+);");
java.util.regex.Matcher matcher = numericEntityPattern.matcher(input);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
int codePoint = Integer.parseInt(matcher.group(1));
matcher.appendReplacement(sb, String.valueOf((char) codePoint));
}
matcher.appendTail(sb);
return sb.toString();
}
// 文件名安全化
public static String sanitizeFileName(String fileName) {
if (fileName == null || fileName.isEmpty()) {
return "unknown";
}
// 移除路径
fileName = fileName.replaceAll("[/\\\\]", "");
// 移除非字母数字字符(保留点、下划线、连字符)
fileName = fileName.replaceAll("[^\\w.-]", "_");
// 限制长度
if (fileName.length() > 255) {
int extensionIndex = fileName.lastIndexOf(".");
if (extensionIndex > 0) {
String name = fileName.substring(0, 250);
String extension = fileName.substring(extensionIndex);
fileName = name + extension;
} else {
fileName = fileName.substring(0, 255);
}
}
return fileName;
}
// 敏感数据脱敏
public static String maskSensitiveData(String data, String type) {
if (data == null || data.isEmpty()) {
return data;
}
switch (type.toUpperCase()) {
case "CREDIT_CARD":
if (data.length() >= 16) {
return "****-****-****-" + data.substring(data.length() - 4);
}
break;
case "PHONE":
if (data.length() >= 11) {
return data.substring(0, 3) + "****" + data.substring(data.length() - 4);
}
break;
case "EMAIL":
int atIndex = data.indexOf("@");
if (atIndex > 0) {
return data.charAt(0) + "****" + data.substring(atIndex - 1);
}
break;
case "ID_CARD":
if (data.length() >= 18) {
return data.substring(0, 4) + "**********" + data.substring(data.length() - 4);
}
break;
default:
// 默认脱敏
if (data.length() > 8) {
return data.substring(0, 4) + "****" + data.substring(data.length() - 4);
}
}
return "****";
}
// 时间盲注检测
public static boolean checkTimeBasedInjection(String input) {
if (input == null || input.isEmpty()) {
return false;
}
// 检测时间延迟函数
Pattern timePattern = Pattern.compile(
"SLEEP\\s*\\(|" +
"BENCHMARK\\s*\\(|" +
"WAITFOR\\s+DELAY|" +
"pg_sleep\\s*\\(|" +
"DBMS_LOCK\\.SLEEP|" +
"\\w+\\.wait\\s*\\(|" +
"time\\s*\\(.*\\)|" +
"delay\\s*\\(|" +
"usleep\\s*\\(",
Pattern.CASE_INSENSITIVE
);
return timePattern.matcher(input).find();
}
// 布尔注入检测
public static boolean checkBooleanInjection(String input) {
if (input == null || input.isEmpty()) {
return false;
}
// 检测布尔注入模式
Pattern booleanPattern = Pattern.compile(
"'.*?OR.*?'.*?=.*?'.*?|" +
"'.*?AND.*?'.*?=.*?'.*?|" +
"\\d+\\s*=\\s*\\d+|" +
"\\d+\\s*!=\\s*\\d+|" +
"\\d+\\s*<\\s*\\d+|" +
"\\d+\\s*>\\s*\\d+|" +
"'\\s*=\\s*'|" +
"'\\s*!=\\s*'",
Pattern.CASE_INSENSITIVE
);
return booleanPattern.matcher(input).find();
}
}
8 配置类
package com.waf.config;
import java.io.InputStream;
import java.util.Properties;
import java.util.logging.Logger;
public class WafConfig {
private static final Logger LOG = Logger.getLogger(WafConfig.class.getName());
private static final String CONFIG_FILE = "waf.properties";
private boolean enabled = true;
private boolean sqlInjectionEnabled = true;
private boolean xssEnabled = true;
private boolean csrfEnabled = true;
private boolean pathTraversalEnabled = true;
private boolean fileUploadEnabled = true;
private boolean rateLimitEnabled = false;
private int maxRequestSize = 10 * 1024 * 1024; // 10MB
private int rateLimit = 100; // 每秒请求数限制
private String[] excludedPaths;
private String[] allowedIpList;
public static WafConfig loadConfig() {
WafConfig config = new WafConfig();
try (InputStream input = WafConfig.class.getClassLoader()
.getResourceAsStream(CONFIG_FILE)) {
if (input != null) {
Properties props = new Properties();
props.load(input);
config.setEnabled(Boolean.parseBoolean(
props.getProperty("waf.enabled", "true")));
config.setSqlInjectionEnabled(Boolean.parseBoolean(
props.getProperty("waf.sql.injection.enabled", "true")));
config.setXssEnabled(Boolean.parseBoolean(
props.getProperty("waf.xss.enabled", "true")));
config.setCsrfEnabled(Boolean.parseBoolean(
props.getProperty("waf.csrf.enabled", "true")));
config.setPathTraversalEnabled(Boolean.parseBoolean(
props.getProperty("waf.path.traversal.enabled", "true")));
config.setFileUploadEnabled(Boolean.parseBoolean(
props.getProperty("waf.file.upload.enabled", "true")));
config.setRateLimitEnabled(Boolean.parseBoolean(
props.getProperty("waf.rate.limit.enabled", "false")));
String maxSize = props.getProperty("waf.max.request.size");
if (maxSize != null) {
config.setMaxRequestSize(Integer.parseInt(maxSize));
}
String rateLimit = props.getProperty("waf.rate.limit");
if (rateLimit != null) {
config.setRateLimit(Integer.parseInt(rateLimit));
}
String excluded = props.getProperty("waf.excluded.paths");
if (excluded != null) {
config.setExcludedPaths(excluded.split(","));
}
String allowedIps = props.getProperty("waf.allowed.ips");
if (allowedIps != null) {
config.setAllowedIpList(allowedIps.split(","));
}
}
} catch (Exception e) {
LOG.warning("Failed to load WAF config, using defaults: " + e.getMessage());
}
return config;
}
// Getters and Setters
public boolean isEnabled() { return enabled; }
public void setEnabled(boolean enabled) { this.enabled = enabled; }
public boolean isSqlInjectionEnabled() { return sqlInjectionEnabled; }
public void setSqlInjectionEnabled(boolean enabled) { this.sqlInjectionEnabled = enabled; }
public boolean isXssEnabled() { return xssEnabled; }
public void setXssEnabled(boolean enabled) { this.xssEnabled = enabled; }
public boolean isCsrfEnabled() { return csrfEnabled; }
public void setCsrfEnabled(boolean enabled) { this.csrfEnabled = enabled; }
public boolean isPathTraversalEnabled() { return pathTraversalEnabled; }
public void setPathTraversalEnabled(boolean enabled) { this.pathTraversalEnabled = enabled; }
public boolean isFileUploadEnabled() { return fileUploadEnabled; }
public void setFileUploadEnabled(boolean enabled) { this.fileUploadEnabled = enabled; }
public boolean isRateLimitEnabled() { return rateLimitEnabled; }
public void setRateLimitEnabled(boolean enabled) { this.rateLimitEnabled = enabled; }
public int getMaxRequestSize() { return maxRequestSize; }
public void setMaxRequestSize(int size) { this.maxRequestSize = size; }
public int getRateLimit() { return rateLimit; }
public void setRateLimit(int limit) { this.rateLimit = limit; }
public String[] getExcludedPaths() { return excludedPaths; }
public void setExcludedPaths(String[] paths) { this.excludedPaths = paths; }
public String[] getAllowedIpList() { return allowedIpList; }
public void setAllowedIpList(String[] ips) { this.allowedIpList = ips; }
// 检查路径是否被排除
public boolean isExcludedPath(String path) {
if (excludedPaths == null) {
return false;
}
for (String excludedPath : excludedPaths) {
if (path.startsWith(excludedPath.trim())) {
return true;
}
}
return false;
}
// 检查IP是否允许
public boolean isIpAllowed(String ip) {
if (allowedIpList == null || allowedIpList.length == 0) {
return true;
}
for (String allowedIp : allowedIpList) {
if (allowedIp.trim().equals(ip)) {
return true;
}
}
return false;
}
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播