Checkmarx扫描报Deserialization of Untrusted Data问题,无XSD如何修复?
修复XStream不可信数据反序列化问题(无XSD场景)
核心问题
XStream默认不对反序列化的类做限制,攻击者可构造恶意XML触发危险类实例化,Checkmarx标记的正是这个风险。无需XSD,通过类白名单限制即可解决。
具体修复方案
1. 精确指定允许反序列化的类(推荐)
直接限定仅MyMessage及它依赖的必要类能被反序列化,代码示例:
String message = request.getParameter("param_name"); // Input xml string XStream parser = new XStream(new StaxDriver()); // 只开放MyMessage类(如果MyMessage包含自定义内部类/子类,需一并添加) parser.allowTypes(new Class[]{MyMessage.class}); // 示例:若MyMessage包含InnerData类,需补充 // parser.allowTypes(new Class[]{MyMessage.class, InnerData.class}); MyMessage messageObj = (MyMessage) parser.fromXML(message);
Checkmarx会认可这种白名单限制,因为不可信输入无法实例化未被授权的危险类。
2. 基于包的白名单(适合同类较多场景)
如果使用XStream 1.4.7及以上版本,可通过包名批量开放类,同时启用默认安全配置:
String message = request.getParameter("param_name"); XStream parser = new XStream(new StaxDriver()); // 启用XStream默认安全限制 XStream.setupDefaultSecurity(parser); // 开放指定包下所有类(替换为你的实际包名) parser.allowTypesByWildcard(new String[]{"com.yourcompany.yourpackage.**"}); MyMessage messageObj = (MyMessage) parser.fromXML(message);
3. 额外的XML结构校验(可选增强)
即使没有XSD,也可手动校验XML结构,确保仅包含MyMessage预期的节点,避免恶意注入。示例实现一个简单的结构校验:
private boolean validateXmlStructure(String xml, String expectedRoot) { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new InputSource(new StringReader(xml))); // 校验根节点名称 if (!expectedRoot.equals(doc.getDocumentElement().getNodeName())) { return false; } // 可添加更多校验:比如子节点数量、节点名称是否符合预期等 NodeList childNodes = doc.getDocumentElement().getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node node = childNodes.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { // 检查节点是否为MyMessage的合法字段 String nodeName = node.getNodeName(); if (!Arrays.asList("field1", "field2").contains(nodeName)) { // 替换为你的实际字段名 return false; } } } return true; } catch (Exception e) { return false; } }
使用时先校验再反序列化:
String message = request.getParameter("param_name"); if (!validateXmlStructure(message, "MyMessage")) { throw new IllegalArgumentException("Invalid XML input"); } XStream parser = new XStream(new StaxDriver()); parser.allowTypes(new Class[]{MyMessage.class}); MyMessage messageObj = (MyMessage) parser.fromXML(message);
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

