Web 應用安全防護的第一道防線往往建立在 Servlet Filter 之上。本文提供一套基於 javax.servlet.Filter 的完整實現,涵蓋 SQL 注入關鍵字過濾、XSS 跨站腳本攻擊清洗、請求參數包裝與白名單放行機制,並附帶 web.xml 配置示例。
通過繼承 HttpServletRequestWrapper 覆寫參數獲取方法,實現對所有輸入參數的統一攔截與清洗:
public class RequestWrapper extends HttpServletRequestWrapper {
// 覆寫 getParameter、getParameterValues、getHeader
// 內部調用 cleanXSS(cleanSQLInject(originalValue))
}
public String cleanSQLInject(String src) {
String temp = src;
src = src.replaceAll("insert", "forbidI")
.replaceAll("select", "forbidS")
.replaceAll("update", "forbidU")
.replaceAll("delete", "forbidD")
.replaceAll("and", "forbidA")
.replaceAll("or", "forbidO");
if (!temp.equals(src)) {
log.warn("檢測到 SQL 注入嘗試: 原始=" + temp + ", 處理後=" + src);
}
return src;
}
注意:此為簡易黑名單替換方案,生產環境強烈建議使用參數化查詢(PreparedStatement)或 ORM 框架內建防護,不可僅依賴過濾器。
public String cleanXSS(String src) {
String temp = src;
src = src.replaceAll("<", "<").replaceAll(">", ">")
.replaceAll("\\(", "(").replaceAll("\\)", ")")
.replaceAll("'", "'")
.replaceAll("eval\\((.*)\\)", "")
.replaceAll("[\\\"\\'][\\s]*javascript:(.*)[\\\"\\']", "\"\"")
.replaceAll("script", "").replaceAll(";", "")
.replaceAll("\"", "").replaceAll("@", "")
.replaceAll("0x0d", "").replaceAll("0x0a", "").replaceAll(",", "");
if (!temp.equals(src)) {
log.warn("檢測到 XSS 攻擊嘗試: 原始=" + temp + ", 處理後=" + src);
}
return src;
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
boolean urlOnly = true; // true: 僅驗證 URL;false: 驗證所有參數
if (urlOnly) {
HttpServletRequest request = (HttpServletRequest) req;
String requestURI = URLDecoder.decode(request.getRequestURL().toString(), "UTF-8");
// 白名單放行:支付回調、登入頁等無需過濾
if (isWhitelisted(requestURI)) {
chain.doFilter(req, resp);
return;
}
RequestWrapper wrapper = new RequestWrapper(request);
String queryString = request.getQueryString();
if (queryString != null && !queryString.isEmpty()) {
String decodedParam = URLDecoder.decode(queryString, "UTF-8");
String sqlCleaned = wrapper.cleanSQLInject(decodedParam);
String xssCleaned = wrapper.cleanXSS(sqlCleaned);
if (!xssCleaned.equals(decodedParam)) {
// 發現惡意內容,重定向到清洗後的 URL
response.sendRedirect(requestURI + "?" + xssCleaned);
return;
}
}
chain.doFilter(req, resp);
} else {
// 嚴格模式:包裝請求對象,所有參數獲取自動清洗
chain.doFilter(new RequestWrapper((HttpServletRequest) req), resp);
}
}
<filter>
<filter-name>XssFilter</filter-name>
<filter-class>cn.com.jsoft.xss.XSSFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>XssFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
#{} 參數綁定。<c:out>、Thymeleaf th:text)+ 內容安全策略(CSP)Header。本文提供的過濾器代碼可作為安全防護的「補丁層」快速接入舊系統,但切記:參數化查詢與輸出編碼才是根治漏洞的正道。安全防護應建立多層體系:輸入驗證 → 業務邏輯參數化 → 輸出編碼 → WAF/防火牆。