字符串关键词匹配可以用于业务文本检查,但不能阻止 SQL 注入。SQL 安全首先使用参数化查询;把包含 insert、update 的 HTTP 请求一律拦截,会误伤正常文本,也能被其他写法绕过。

在业务字段中检查

下面是 JDK 8+ 的独立练习,保存为 WordCheckDemo.java。使用虚构词表,返回命中的词,不修改原文:

import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
public class WordCheckDemo {
private static final List<String> WORDS = Arrays.asList("demo-blocked", "sample-blocked");
public static List<String> find(String text) {
if (text == null) return java.util.Collections.emptyList();
String normalized = text.toLowerCase(Locale.ROOT);
return WORDS.stream().filter(normalized::contains).collect(Collectors.toList());
}
public static void main(String[] args) {
System.out.println(find("包含 DEMO-BLOCKED 的测试内容"));
System.out.println(find("普通内容"));
}
}
Terminal window
javac -encoding UTF-8 WordCheckDemo.java
java WordCheckDemo

输出分别是 [demo-blocked] 与 []。在 Controller 把 JSON 解析成 DTO 后,对需要检查的文本字段调用,按业务规则决定提示或拒绝。

为什么不直接读取所有 HTTP 请求体

Servlet 请求体默认只能读取一次。Filter 读完后继续把原 request 交给 Controller,会使后者拿不到正文;需要可重放的包装请求,并限制读取大小、内容类型和字符编码。

WebFlux 的请求体是异步流,不能先手动 subscribe() 再立即从 AtomicReference 取结果。检查与继续转发必须处于同一响应式链,合并 DataBuffer 时还需限制大小、正确释放并重建下游可读取的 body。

这些处理比字段级检查复杂,因此入门示例直接在解析后的业务文本上调用。词表、大小写、空白和 Unicode 归一化规则要另行定义;短词表的 contains 示例不宣称具有完整内容审核能力。

参考:OWASP 参数化查询说明、Spring WebFlux DataBuffer。