1 package com.jsql.util;
2
3 import com.jsql.model.InjectionModel;
4 import com.jsql.model.exception.JSqlException;
5 import org.apache.commons.lang3.StringUtils;
6 import org.apache.logging.log4j.LogManager;
7 import org.apache.logging.log4j.Logger;
8 import org.w3c.dom.Document;
9 import org.w3c.dom.Node;
10 import org.xml.sax.InputSource;
11 import org.xml.sax.SAXException;
12
13 import javax.xml.XMLConstants;
14 import javax.xml.parsers.DocumentBuilderFactory;
15 import javax.xml.parsers.ParserConfigurationException;
16 import javax.xml.transform.TransformerException;
17 import javax.xml.transform.TransformerFactory;
18 import javax.xml.transform.dom.DOMSource;
19 import javax.xml.transform.stream.StreamResult;
20 import java.io.IOException;
21 import java.io.StringReader;
22 import java.io.StringWriter;
23 import java.util.regex.Pattern;
24
25 public class SoapUtil {
26
27
28
29
30 private static final Logger LOGGER = LogManager.getRootLogger();
31
32 private final InjectionModel injectionModel;
33
34 public SoapUtil(InjectionModel injectionModel) {
35 this.injectionModel = injectionModel;
36 }
37
38 public boolean testParameters(boolean hasFoundInjection) {
39 if (!hasFoundInjection) {
40 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "{} SOAP...", () -> I18nUtil.valueByKey("LOG_CHECKING"));
41 } else {
42 return true;
43 }
44
45 if (
46 this.injectionModel.getMediatorUtils().getPreferencesUtil().isCheckingAllSoapParam()
47 && this.injectionModel.getMediatorUtils().getParameterUtil().isRequestSoap()
48 ) {
49 try {
50 var doc = SoapUtil.convertToDocument(this.injectionModel.getMediatorUtils().getParameterUtil().getRawRequest());
51 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Parsing SOAP from Request...");
52 return this.isTextNodeInjectable(doc, doc.getDocumentElement());
53 } catch (Exception e) {
54 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "SOAP not detected");
55 }
56 }
57 return false;
58 }
59
60 public static Document convertToDocument(String xmlStr) throws ParserConfigurationException, SAXException, IOException {
61 var factory = DocumentBuilderFactory.newInstance();
62 factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, StringUtils.EMPTY);
63 factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, StringUtils.EMPTY);
64 factory.setAttribute(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
65 factory.setExpandEntityReferences(false);
66 var builder = factory.newDocumentBuilder();
67 return builder.parse(new InputSource(new StringReader(xmlStr)));
68 }
69
70 public boolean isTextNodeInjectable(Document doc, Node node) {
71 var nodeList = node.getChildNodes();
72 for (var i = 0; i < nodeList.getLength(); i++) {
73 var currentNode = nodeList.item(i);
74 if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
75 if (this.isTextNodeInjectable(doc, currentNode)) {
76 return true;
77 }
78 } else if (currentNode.getNodeType() == Node.TEXT_NODE) {
79
80 SoapUtil.removeInjectionPoint(doc, doc.getDocumentElement());
81 currentNode.setTextContent(currentNode.getTextContent().replace(InjectionModel.STAR, StringUtils.EMPTY) + InjectionModel.STAR);
82 this.injectionModel.getMediatorUtils().getParameterUtil().initRequest(SoapUtil.convertDocumentToString(doc));
83
84 try {
85 LOGGER.log(
86 LogLevelUtil.CONSOLE_INFORM,
87 "{} SOAP {}={}",
88 () -> I18nUtil.valueByKey("LOG_CHECKING"),
89 () -> currentNode.getParentNode().getNodeName(),
90 () -> currentNode.getTextContent().replace(InjectionModel.STAR, StringUtils.EMPTY)
91 );
92 if (this.injectionModel.getMediatorMethod().getRequest().testParameters()) {
93 return true;
94 }
95 } catch (JSqlException e) {
96
97 LOGGER.log(
98 LogLevelUtil.CONSOLE_ERROR,
99 String.format(
100 "No SOAP Request injection for %s=%s",
101 currentNode.getParentNode().getNodeName(),
102 currentNode.getTextContent().replace(InjectionModel.STAR, StringUtils.EMPTY)
103 )
104 );
105 }
106 }
107 }
108 return false;
109 }
110
111 public static void removeInjectionPoint(Document doc, Node node) {
112 var nodeList = node.getChildNodes();
113 for (var i = 0; i < nodeList.getLength(); i++) {
114 var currentNode = nodeList.item(i);
115 if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
116 SoapUtil.removeInjectionPoint(doc, currentNode);
117 } else if (currentNode.getNodeType() == Node.TEXT_NODE) {
118 currentNode.setTextContent(
119 currentNode
120 .getTextContent()
121 .replaceAll(Pattern.quote(InjectionModel.STAR) + "*$", StringUtils.EMPTY)
122 );
123 }
124 }
125 }
126
127 private static String convertDocumentToString(Document doc) {
128 var transformerFactory = TransformerFactory.newInstance();
129 transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, StringUtils.EMPTY);
130 transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, StringUtils.EMPTY);
131
132 String output = null;
133 try {
134 var transformer = transformerFactory.newTransformer();
135 var writer = new StringWriter();
136 transformer.transform(new DOMSource(doc), new StreamResult(writer));
137 output = writer.getBuffer().toString();
138 } catch (TransformerException e) {
139
140 }
141 return output;
142 }
143 }