
本文介绍如何在java web应用中对上传文件(pdf/excel)及用户文本输入实施运行时安全校验,防范xss、命令注入与宏恶意行为,并结合正则匹配、apache poi/pdfbox等工具实现轻量级客户端风险拦截。
本文介绍如何在java web应用中对上传文件(pdf/excel)及用户文本输入实施运行时安全校验,防范xss、命令注入与宏恶意行为,并结合正则匹配、apache poi/pdfbox等工具实现轻量级客户端风险拦截。
在构建企业级Java Web应用时,文件上传与用户自由输入是高风险入口——攻击者可能通过嵌入JavaScript的PDF自动执行XSS、利用Excel公式或DDE函数触发本地命令执行(如cmd.exe)、或在导出Excel的文本字段中注入恶意脚本污染前端渲染。仅依赖服务端MIME类型校验或后端杀毒扫描远远不足,必须在文件解析阶段实施内容级语义检测。
以下为可落地的分层校验方案:
一、PDF文件的JavaScript行为拦截
使用Apache PDFBox检测文档级JavaScript自动执行行为(如OpenAction),这是PDF XSS和恶意跳转的常见载体:
public static void pdfJavascriptCodeCheck(byte[] contents) throws PossibleXSSException {
try (PDDocument document = PDDocument.load(new ByteArrayInputStream(contents))) {
PDAction openAction = document.getDocumentCatalog().getOpenAction();
if (openAction instanceof PDActionJavaScript) {
throw new PossibleXSSException("PDF contains dangerous OpenAction JavaScript");
}
} catch (IOException e) {
throw new RuntimeException("Failed to parse PDF", e);
}
}⚠️ 注意:PDActionJavaScript仅捕获显式OpenAction;还需扩展检查AdditionalActions(如WC/WillSave)及嵌入的富媒体JS对象,建议配合document.getDocument().getNamesTree()遍历所有命名动作。
立即学习“Java免费学习笔记(深入)”;
二、Excel文件的危险公式与DDE注入检测
Excel中的=CMD|' /C calc'!A0类DDE公式或=HYPERLINK("javascript:alert(1)")等可触发任意命令或前端脚本。我们使用Apache POI逐单元格扫描:
private void checkJavaScriptCodeOnRow(Row row) throws PossiblePrivilegeScalingException {
for (Cell cell : row) {
String value = getCellStringValue(cell); // 兼容FormulaCell → evaluate & toString()
if (PrivilegeScalingRegexValidator.isDangerousFormula(value)) {
throw new PossiblePrivilegeScalingException(
"Suspicious formula detected: " + value.substring(0, Math.min(50, value.length()))
);
}
}
}配套正则需覆盖主流攻击模式:
public class PrivilegeScalingRegexValidator {
// 匹配 DDE (=CMD|...), HYPERLINK(js), SHELL(), EXEC(), 以及含引号+空格的危险命令片段
private static final String DANGEROUS_PATTERN =
"(?i)=.*?(?:CMD\||SHELL\(|EXEC\(|HYPERLINK\([^)]*javascript:|\|'.*?'!|\s+cmd\.exe|/c\s+calc)";
public static boolean isDangerousFormula(String input) {
return input != null && Pattern.compile(DANGEROUS_PATTERN).matcher(input).find();
}
}✅ 提示:getCellStringValue()应先调用cell.getCellType()判断类型,对CELL_TYPE_FORMULA需用FormulaEvaluator计算后再校验,避免漏检隐藏逻辑。
三、用户文本输入的XSS预过滤(导出Excel前)
当用户输入内容将写入Excel单元格或HTML页面时,须双重防护:
-
输出编码:导出Excel时,对所有字符串调用
StringEscapeUtils.escapeHtml4()(Apache Commons Text); -
上下文感知过滤:若该字段最终渲染为HTML,使用OWASP Java Encoder的
Encode.forHtmlContent();若用于JavaScript上下文,则用Encode.forJavaScript(); -
禁止富文本直接插入:禁用
<script></script>、onerror=、javascript:等关键词,推荐使用Jsoup进行白名单净化:String safeHtml = Jsoup.clean(userInput, Whitelist.relaxed().addTags("p", "br"));
四、运行时集成建议
- ✅ 分层防御:校验器应作为Spring
@ControllerAdvice或Filter链一环,在MultipartFile.transferTo()前完成验证; - ✅ 性能优化:大文件(>10MB)启用流式校验(如PDFBox支持
MemoryUsageSetting.setupTempFileOnly()); - ✅ 联动杀毒:校验通过后,再交由ClamAV或商用引擎(如McAfee SDK)做二进制扫描,避免重复IO;
- ⚠️ 不替代客户端防护:前端仍需限制文件类型(
accept="application/pdf,.xlsx")、大小,并禁用<iframe></iframe>直接渲染用户上传PDF。
综上,安全不是单点功能,而是贯穿文件解析、数据流转、模板渲染的全链路约束。通过语义化校验+上下文编码+多引擎协同,可显著降低因文件上传与用户输入导致的RCE、XSS与横向渗透风险。


















