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 | * Log4j logger sent to view. | |
29 | */ | |
30 | private static final Logger LOGGER = LogManager.getRootLogger(); | |
31 | ||
32 | private final InjectionModel injectionModel; | |
33 | | |
34 | public SoapUtil(InjectionModel injectionModel) { | |
35 | | |
36 | this.injectionModel = injectionModel; | |
37 | } | |
38 | ||
39 | public boolean testParameters(boolean hasFoundInjection) { | |
40 | ||
41 |
1
1. testParameters : negated conditional → NO_COVERAGE |
if (!hasFoundInjection) { |
42 | LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Checking SOAP params..."); | |
43 | } else { | |
44 |
1
1. testParameters : replaced boolean return with false for com/jsql/util/SoapUtil::testParameters → NO_COVERAGE |
return true; |
45 | } | |
46 | ||
47 | if ( | |
48 |
1
1. testParameters : negated conditional → NO_COVERAGE |
this.injectionModel.getMediatorUtils().getPreferencesUtil().isCheckingAllSoapParam() |
49 |
1
1. testParameters : negated conditional → NO_COVERAGE |
&& this.injectionModel.getMediatorUtils().getParameterUtil().isRequestSoap() |
50 | ) { | |
51 | try { | |
52 | var doc = SoapUtil.convertToDocument(this.injectionModel.getMediatorUtils().getParameterUtil().getRawRequest()); | |
53 | LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Parsing SOAP from Request..."); | |
54 | | |
55 |
2
1. testParameters : replaced boolean return with false for com/jsql/util/SoapUtil::testParameters → NO_COVERAGE 2. testParameters : replaced boolean return with true for com/jsql/util/SoapUtil::testParameters → NO_COVERAGE |
return this.isTextNodeInjectable(doc, doc.getDocumentElement()); |
56 | | |
57 | } catch (Exception e) { | |
58 | LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "SOAP not detected"); | |
59 | } | |
60 | } | |
61 | | |
62 |
1
1. testParameters : replaced boolean return with true for com/jsql/util/SoapUtil::testParameters → NO_COVERAGE |
return false; |
63 | } | |
64 | | |
65 | public static Document convertToDocument(String xmlStr) throws ParserConfigurationException, SAXException, IOException { | |
66 | | |
67 | var factory = DocumentBuilderFactory.newInstance(); | |
68 | | |
69 |
1
1. convertToDocument : removed call to javax/xml/parsers/DocumentBuilderFactory::setAttribute → NO_COVERAGE |
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, StringUtils.EMPTY); |
70 |
1
1. convertToDocument : removed call to javax/xml/parsers/DocumentBuilderFactory::setAttribute → NO_COVERAGE |
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, StringUtils.EMPTY); |
71 |
1
1. convertToDocument : removed call to javax/xml/parsers/DocumentBuilderFactory::setAttribute → NO_COVERAGE |
factory.setAttribute(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE); |
72 |
1
1. convertToDocument : removed call to javax/xml/parsers/DocumentBuilderFactory::setExpandEntityReferences → NO_COVERAGE |
factory.setExpandEntityReferences(false); |
73 | ||
74 | var builder = factory.newDocumentBuilder(); | |
75 | | |
76 |
1
1. convertToDocument : replaced return value with null for com/jsql/util/SoapUtil::convertToDocument → NO_COVERAGE |
return builder.parse(new InputSource(new StringReader(xmlStr))); |
77 | } | |
78 | ||
79 | public boolean isTextNodeInjectable(Document doc, Node node) { | |
80 | | |
81 | var nodeList = node.getChildNodes(); | |
82 | ||
83 |
2
1. isTextNodeInjectable : negated conditional → NO_COVERAGE 2. isTextNodeInjectable : changed conditional boundary → NO_COVERAGE |
for (var i = 0; i < nodeList.getLength(); i++) { |
84 | | |
85 | var currentNode = nodeList.item(i); | |
86 | | |
87 |
1
1. isTextNodeInjectable : negated conditional → NO_COVERAGE |
if (currentNode.getNodeType() == Node.ELEMENT_NODE) { |
88 | //calls this method for all the children which is Element | |
89 |
1
1. isTextNodeInjectable : negated conditional → NO_COVERAGE |
if (this.isTextNodeInjectable(doc, currentNode)) { |
90 |
1
1. isTextNodeInjectable : replaced boolean return with false for com/jsql/util/SoapUtil::isTextNodeInjectable → NO_COVERAGE |
return true; |
91 | } | |
92 |
1
1. isTextNodeInjectable : negated conditional → NO_COVERAGE |
} else if (currentNode.getNodeType() == Node.TEXT_NODE) { |
93 | | |
94 |
1
1. isTextNodeInjectable : removed call to com/jsql/util/SoapUtil::removeInjectionPoint → NO_COVERAGE |
SoapUtil.removeInjectionPoint(doc, doc.getDocumentElement()); |
95 | | |
96 |
1
1. isTextNodeInjectable : removed call to org/w3c/dom/Node::setTextContent → NO_COVERAGE |
currentNode.setTextContent(currentNode.getTextContent().replace(InjectionModel.STAR, StringUtils.EMPTY) + InjectionModel.STAR); |
97 | | |
98 |
1
1. isTextNodeInjectable : removed call to com/jsql/util/ParameterUtil::initializeRequest → NO_COVERAGE |
this.injectionModel.getMediatorUtils().getParameterUtil().initializeRequest(SoapUtil.convertDocumentToString(doc)); |
99 | | |
100 | try { | |
101 | LOGGER.log( | |
102 | LogLevelUtil.CONSOLE_INFORM, | |
103 | "Checking SOAP Request injection for {}={}", | |
104 |
1
1. lambda$isTextNodeInjectable$0 : replaced return value with null for com/jsql/util/SoapUtil::lambda$isTextNodeInjectable$0 → NO_COVERAGE |
() -> currentNode.getParentNode().getNodeName(), |
105 |
1
1. lambda$isTextNodeInjectable$1 : replaced return value with null for com/jsql/util/SoapUtil::lambda$isTextNodeInjectable$1 → NO_COVERAGE |
() -> currentNode.getTextContent().replace(InjectionModel.STAR, StringUtils.EMPTY) |
106 | ); | |
107 | | |
108 |
1
1. isTextNodeInjectable : negated conditional → NO_COVERAGE |
if (this.injectionModel.getMediatorMethod().getRequest().testParameters()) { |
109 |
1
1. isTextNodeInjectable : replaced boolean return with false for com/jsql/util/SoapUtil::isTextNodeInjectable → NO_COVERAGE |
return true; |
110 | } | |
111 | } catch (JSqlException e) { | |
112 | // Injection failure | |
113 | LOGGER.log( | |
114 | LogLevelUtil.CONSOLE_ERROR, | |
115 | String.format( | |
116 | "No SOAP Request injection for %s=%s", | |
117 | currentNode.getParentNode().getNodeName(), | |
118 | currentNode.getTextContent().replace(InjectionModel.STAR, StringUtils.EMPTY) | |
119 | ) | |
120 | ); | |
121 | } | |
122 | } | |
123 | } | |
124 | | |
125 |
1
1. isTextNodeInjectable : replaced boolean return with true for com/jsql/util/SoapUtil::isTextNodeInjectable → NO_COVERAGE |
return false; |
126 | } | |
127 | ||
128 | public static void removeInjectionPoint(Document doc, Node node) { | |
129 | | |
130 | var nodeList = node.getChildNodes(); | |
131 | | |
132 |
2
1. removeInjectionPoint : negated conditional → NO_COVERAGE 2. removeInjectionPoint : changed conditional boundary → NO_COVERAGE |
for (var i = 0; i < nodeList.getLength(); i++) { |
133 | | |
134 | var currentNode = nodeList.item(i); | |
135 | | |
136 |
1
1. removeInjectionPoint : negated conditional → NO_COVERAGE |
if (currentNode.getNodeType() == Node.ELEMENT_NODE) { |
137 | //calls this method for all the children which is Element | |
138 |
1
1. removeInjectionPoint : removed call to com/jsql/util/SoapUtil::removeInjectionPoint → NO_COVERAGE |
SoapUtil.removeInjectionPoint(doc, currentNode); |
139 |
1
1. removeInjectionPoint : negated conditional → NO_COVERAGE |
} else if (currentNode.getNodeType() == Node.TEXT_NODE) { |
140 |
1
1. removeInjectionPoint : removed call to org/w3c/dom/Node::setTextContent → NO_COVERAGE |
currentNode.setTextContent( |
141 | currentNode | |
142 | .getTextContent() | |
143 | .replaceAll(Pattern.quote(InjectionModel.STAR) + "*$", StringUtils.EMPTY) | |
144 | ); | |
145 | } | |
146 | } | |
147 | } | |
148 | | |
149 | private static String convertDocumentToString(Document doc) { | |
150 | | |
151 | var transformerFactory = TransformerFactory.newInstance(); | |
152 |
1
1. convertDocumentToString : removed call to javax/xml/transform/TransformerFactory::setAttribute → NO_COVERAGE |
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, StringUtils.EMPTY); |
153 |
1
1. convertDocumentToString : removed call to javax/xml/transform/TransformerFactory::setAttribute → NO_COVERAGE |
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, StringUtils.EMPTY); |
154 | | |
155 | String output = null; | |
156 | | |
157 | try { | |
158 | var transformer = transformerFactory.newTransformer(); | |
159 | var writer = new StringWriter(); | |
160 |
1
1. convertDocumentToString : removed call to javax/xml/transform/Transformer::transform → NO_COVERAGE |
transformer.transform(new DOMSource(doc), new StreamResult(writer)); |
161 | output = writer.getBuffer().toString(); | |
162 | | |
163 | } catch (TransformerException e) { | |
164 | // ignore | |
165 | } | |
166 | | |
167 |
1
1. convertDocumentToString : replaced return value with "" for com/jsql/util/SoapUtil::convertDocumentToString → NO_COVERAGE |
return output; |
168 | } | |
169 | } | |
Mutations | ||
41 |
1.1 |
|
44 |
1.1 |
|
48 |
1.1 |
|
49 |
1.1 |
|
55 |
1.1 2.2 |
|
62 |
1.1 |
|
69 |
1.1 |
|
70 |
1.1 |
|
71 |
1.1 |
|
72 |
1.1 |
|
76 |
1.1 |
|
83 |
1.1 2.2 |
|
87 |
1.1 |
|
89 |
1.1 |
|
90 |
1.1 |
|
92 |
1.1 |
|
94 |
1.1 |
|
96 |
1.1 |
|
98 |
1.1 |
|
104 |
1.1 |
|
105 |
1.1 |
|
108 |
1.1 |
|
109 |
1.1 |
|
125 |
1.1 |
|
132 |
1.1 2.2 |
|
136 |
1.1 |
|
138 |
1.1 |
|
139 |
1.1 |
|
140 |
1.1 |
|
152 |
1.1 |
|
153 |
1.1 |
|
160 |
1.1 |
|
167 |
1.1 |