Java Filter 中需用 HttpServletRequestWrapper 重写 getParameter 等方法实现安全过滤,否则仅字符串替换无效;须覆盖 getParameterMap、getInputStream 等关键方法,采用白名单校验并结合 HTML/JS 编码,避免黑名单绕过。

Java Filter 中如何安全过滤请求参数里的特殊字符
直接在 Filter 里对 request.getParameter() 返回值做字符串替换,基本无效——因为 Servlet 容器在首次调用该方法时已将参数解析并缓存,后续修改原始输入流或包装 request 后不重写 getParameter 等方法,过滤逻辑根本不会生效。
必须用 HttpServletRequestWrapper 包装请求对象
核心是继承 HttpServletRequestWrapper,重写所有可能暴露原始参数的方法(getParameter、getParameterValues、getParameterMap、getHeader 等),并在其中对值做清洗。否则过滤只停留在“看起来处理了”,实际业务代码拿到的仍是未过滤数据。
常见遗漏点:
- 忘记重写
getParameterMap()—— Spring MVC 等框架常通过该方法批量取参 - 没处理
getInputStream()和getReader()—— JSON 请求体需额外拦截 - 正则替换使用
String.replace()而非replaceAll(),导致转义失效
过滤逻辑别硬编码正则,优先用白名单 + 工具类
用黑名单(如“去掉 、>、'”)极易绕过;应按业务场景定义允许字符集。例如仅允许中文、英文、数字、下划线、短横线:
立即学习“Java免费学习笔记(深入)”;
public static String cleanParam(String input) {
if (input == null) return null;
return input.replaceAll("[^\\u4e00-\\u9fa5a-zA-Z0-9_-]", "");
}
更稳妥的做法是结合 org.apache.commons.text.StringEscapeUtils 或 OWASP Java Encoder 进行 HTML/JS 上下文编码,而非简单删除——删除可能破坏业务语义(如用户昵称含 emoji 或商标符号®)。
Filter 配置顺序和 URL 匹配要精准
若项目用了 Spring Security 或其他 Filter 链,你的过滤器必须在它们之前执行,否则安全校验可能基于未清洗的数据。在 web.xml 中靠前声明,或用 @WebFilter 的 filterName + order 控制(Spring Boot 推荐用 @Bean 注册并实现 Ordered)。
URL pattern 别写成 /* 就完事:静态资源(/static/**)、健康检查(/actuator/**)通常无需过滤,过度拦截会影响性能和兼容性。
真正难的是区分「哪些参数需要过滤」「在哪个上下文过滤」——比如搜索关键词要防 XSS,但 Base64 编码的图片字段就不能一刀切解码再过滤。得结合 Content-Type、参数名前缀、甚至 Controller 层注解动态决策。










