SoapUtil.java

1
package com.jsql.util;
2
3
import com.jsql.model.InjectionModel;
4
import com.jsql.model.exception.JSqlException;
5
import com.jsql.model.injection.method.AbstractMethodInjection;
6
import org.apache.commons.lang3.StringUtils;
7
import org.apache.logging.log4j.LogManager;
8
import org.apache.logging.log4j.Logger;
9
import org.w3c.dom.Document;
10
import org.w3c.dom.Node;
11
import org.w3c.dom.NodeList;
12
import org.w3c.dom.Text;
13
import org.xml.sax.InputSource;
14
import org.xml.sax.SAXException;
15
16
import javax.xml.XMLConstants;
17
import javax.xml.parsers.DocumentBuilderFactory;
18
import javax.xml.parsers.ParserConfigurationException;
19
import javax.xml.transform.TransformerException;
20
import javax.xml.transform.TransformerFactory;
21
import javax.xml.transform.dom.DOMSource;
22
import javax.xml.transform.stream.StreamResult;
23
import java.io.IOException;
24
import java.io.StringReader;
25
import java.io.StringWriter;
26
import java.util.regex.Pattern;
27
28
public class SoapUtil {
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 1 1. testParameters : negated conditional → NO_COVERAGE
        if (!hasFoundInjection) {
40
            LOGGER.log(
41
                LogLevelUtil.CONSOLE_DEFAULT,
42
                "{} [SOAP] params...",
43 1 1. lambda$testParameters$0 : replaced return value with null for com/jsql/util/SoapUtil::lambda$testParameters$0 → NO_COVERAGE
                () -> I18nUtil.valueByKey(AbstractMethodInjection.LOG_CHECKING)
44
            );
45
        } else {
46 1 1. testParameters : replaced boolean return with false for com/jsql/util/SoapUtil::testParameters → NO_COVERAGE
            return true;
47
        }
48
49
        if (
50 1 1. testParameters : negated conditional → NO_COVERAGE
            this.injectionModel.getMediatorUtils().preferencesUtil().isCheckingAllSoapParam()
51 1 1. testParameters : negated conditional → NO_COVERAGE
            && this.injectionModel.getMediatorUtils().parameterUtil().isRequestSoap()
52
        ) {
53
            try {
54
                LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Parsing SOAP request...");
55 1 1. testParameters : negated conditional → NO_COVERAGE
                if (this.injectionModel.getMediatorUtils().parameterUtil().getRawRequest().contains(InjectionModel.STAR)) {
56 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.injectionModel.getMediatorMethod().getRequest().testParameters();
57
                } else {
58
                    var document = SoapUtil.convertToDocument(this.injectionModel.getMediatorUtils().parameterUtil().getRawRequest());
59 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(document, document.getDocumentElement());
60
                }
61
            } catch (ParserConfigurationException | IOException | SAXException e) {
62
                LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Incorrect SOAP template: {}", e.getMessage());
63
            } catch (JSqlException e) {
64
                LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "No SOAP Request injection");
65
            }
66
        }
67 1 1. testParameters : replaced boolean return with true for com/jsql/util/SoapUtil::testParameters → NO_COVERAGE
        return false;
68
    }
69
    
70
    public static Document convertToDocument(String xmlStr) throws ParserConfigurationException, SAXException, IOException {
71
        var factory = DocumentBuilderFactory.newInstance();
72 1 1. convertToDocument : removed call to javax/xml/parsers/DocumentBuilderFactory::setAttribute → NO_COVERAGE
        factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, StringUtils.EMPTY);
73 1 1. convertToDocument : removed call to javax/xml/parsers/DocumentBuilderFactory::setAttribute → NO_COVERAGE
        factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, StringUtils.EMPTY);
74 1 1. convertToDocument : removed call to javax/xml/parsers/DocumentBuilderFactory::setAttribute → NO_COVERAGE
        factory.setAttribute(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
75 1 1. convertToDocument : removed call to javax/xml/parsers/DocumentBuilderFactory::setExpandEntityReferences → NO_COVERAGE
        factory.setExpandEntityReferences(false);
76
        var builder = factory.newDocumentBuilder();
77 1 1. convertToDocument : replaced return value with null for com/jsql/util/SoapUtil::convertToDocument → NO_COVERAGE
        return builder.parse(new InputSource(new StringReader(xmlStr)));
78
    }
79
80
    public boolean isTextNodeInjectable(Document originDocument, Node node) {
81
        var nodeList = SoapUtil.getNodeList(originDocument, node);
82 2 1. isTextNodeInjectable : changed conditional boundary → NO_COVERAGE
2. isTextNodeInjectable : negated conditional → NO_COVERAGE
        for (var i = 0 ; i < nodeList.getLength() ; i++) {
83
            var currentNode = nodeList.item(i);
84 1 1. isTextNodeInjectable : negated conditional → NO_COVERAGE
            if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
85 1 1. isTextNodeInjectable : negated conditional → NO_COVERAGE
                if (this.isTextNodeInjectable(originDocument, currentNode)) {
86 1 1. isTextNodeInjectable : replaced boolean return with false for com/jsql/util/SoapUtil::isTextNodeInjectable → NO_COVERAGE
                    return true;
87
                }
88
            } else {
89 1 1. isTextNodeInjectable : removed call to com/jsql/util/SoapUtil::removeInjectionPoint → NO_COVERAGE
                SoapUtil.removeInjectionPoint(originDocument, originDocument.getDocumentElement());
90
                var origin = currentNode.getTextContent();
91 1 1. isTextNodeInjectable : removed call to org/w3c/dom/Node::setTextContent → NO_COVERAGE
                currentNode.setTextContent(InjectionModel.STAR);
92 1 1. isTextNodeInjectable : removed call to com/jsql/util/ParameterUtil::initRequest → NO_COVERAGE
                this.injectionModel.getMediatorUtils().parameterUtil().initRequest(SoapUtil.convertDocumentToString(originDocument));
93
94
                try {
95
                    LOGGER.log(
96
                        LogLevelUtil.CONSOLE_INFORM,
97
                        "{} [SOAP] {}={}",
98 1 1. lambda$isTextNodeInjectable$1 : replaced return value with null for com/jsql/util/SoapUtil::lambda$isTextNodeInjectable$1 → NO_COVERAGE
                        () -> I18nUtil.valueByKey(AbstractMethodInjection.LOG_CHECKING),
99 1 1. lambda$isTextNodeInjectable$2 : replaced return value with null for com/jsql/util/SoapUtil::lambda$isTextNodeInjectable$2 → NO_COVERAGE
                        () -> currentNode.getParentNode().getNodeName(),
100 1 1. lambda$isTextNodeInjectable$3 : replaced return value with null for com/jsql/util/SoapUtil::lambda$isTextNodeInjectable$3 → NO_COVERAGE
                        () -> currentNode.getTextContent().replace(InjectionModel.STAR, StringUtils.EMPTY)
101
                    );
102 1 1. isTextNodeInjectable : negated conditional → NO_COVERAGE
                    if (this.injectionModel.getMediatorMethod().getRequest().testParameters()) {
103 1 1. isTextNodeInjectable : replaced boolean return with false for com/jsql/util/SoapUtil::isTextNodeInjectable → NO_COVERAGE
                        return true;
104
                    }
105 1 1. isTextNodeInjectable : removed call to org/w3c/dom/Node::setTextContent → NO_COVERAGE
                    currentNode.setTextContent(origin);  // restore
106
                } catch (JSqlException e) {  // Injection failure
107
                    LOGGER.log(
108
                        LogLevelUtil.CONSOLE_ERROR,
109
                        String.format(
110
                            "No SOAP Request injection for %s=%s",
111
                            currentNode.getParentNode().getNodeName(),
112
                            currentNode.getTextContent().replace(InjectionModel.STAR, StringUtils.EMPTY)
113
                        )
114
                    );
115
                }
116
            }
117
        }
118 1 1. isTextNodeInjectable : replaced boolean return with true for com/jsql/util/SoapUtil::isTextNodeInjectable → NO_COVERAGE
        return false;
119
    }
120
121
    private static NodeList getNodeList(Document originDocument, Node node) {
122
        var nodeList = node.getChildNodes();
123 1 1. getNodeList : negated conditional → NO_COVERAGE
        if (nodeList.getLength() == 0) {  // force node check when empty
124
            try {
125
                var documentBuilderFactory = DocumentBuilderFactory.newInstance();
126
                var document = documentBuilderFactory.newDocumentBuilder().newDocument();
127
                Text textNode = document.createTextNode(StringUtils.EMPTY);
128
                Node nodeWithText = originDocument.importNode(textNode, true);
129
                node.appendChild(nodeWithText);
130
            } catch (ParserConfigurationException e) {
131
                LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
132
            }
133
        }
134 1 1. getNodeList : replaced return value with null for com/jsql/util/SoapUtil::getNodeList → NO_COVERAGE
        return nodeList;
135
    }
136
137
    public static void removeInjectionPoint(Document doc, Node node) {
138
        var nodeList = node.getChildNodes();
139 2 1. removeInjectionPoint : negated conditional → NO_COVERAGE
2. removeInjectionPoint : changed conditional boundary → NO_COVERAGE
        for (var i = 0 ; i < nodeList.getLength() ; i++) {
140
            var currentNode = nodeList.item(i);
141 1 1. removeInjectionPoint : negated conditional → NO_COVERAGE
            if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
142 1 1. removeInjectionPoint : removed call to com/jsql/util/SoapUtil::removeInjectionPoint → NO_COVERAGE
                SoapUtil.removeInjectionPoint(doc, currentNode);  // calls this method for all the children which is Element
143 1 1. removeInjectionPoint : negated conditional → NO_COVERAGE
            } else if (currentNode.getNodeType() == Node.TEXT_NODE) {
144 1 1. removeInjectionPoint : removed call to org/w3c/dom/Node::setTextContent → NO_COVERAGE
                currentNode.setTextContent(
145
                    currentNode
146
                    .getTextContent()
147
                    .replaceAll(Pattern.quote(InjectionModel.STAR) + "*$", StringUtils.EMPTY)
148
                );
149
            }
150
        }
151
    }
152
    
153
    private static String convertDocumentToString(Document doc) {
154
        var transformerFactory = TransformerFactory.newInstance();
155 1 1. convertDocumentToString : removed call to javax/xml/transform/TransformerFactory::setAttribute → NO_COVERAGE
        transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, StringUtils.EMPTY);
156 1 1. convertDocumentToString : removed call to javax/xml/transform/TransformerFactory::setAttribute → NO_COVERAGE
        transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, StringUtils.EMPTY);
157
        
158
        String output = null;
159
        try {
160
            var transformer = transformerFactory.newTransformer();
161
            var writer = new StringWriter();
162 1 1. convertDocumentToString : removed call to javax/xml/transform/Transformer::transform → NO_COVERAGE
            transformer.transform(new DOMSource(doc), new StreamResult(writer));
163
            output = writer.getBuffer().toString();
164
        } catch (TransformerException e) {
165
            // ignore
166
        }
167 1 1. convertDocumentToString : replaced return value with "" for com/jsql/util/SoapUtil::convertDocumentToString → NO_COVERAGE
        return output;
168
    }
169
}

Mutations

39

1.1
Location : testParameters
Killed by : none
negated conditional → NO_COVERAGE

43

1.1
Location : lambda$testParameters$0
Killed by : none
replaced return value with null for com/jsql/util/SoapUtil::lambda$testParameters$0 → NO_COVERAGE

46

1.1
Location : testParameters
Killed by : none
replaced boolean return with false for com/jsql/util/SoapUtil::testParameters → NO_COVERAGE

50

1.1
Location : testParameters
Killed by : none
negated conditional → NO_COVERAGE

51

1.1
Location : testParameters
Killed by : none
negated conditional → NO_COVERAGE

55

1.1
Location : testParameters
Killed by : none
negated conditional → NO_COVERAGE

56

1.1
Location : testParameters
Killed by : none
replaced boolean return with false for com/jsql/util/SoapUtil::testParameters → NO_COVERAGE

2.2
Location : testParameters
Killed by : none
replaced boolean return with true for com/jsql/util/SoapUtil::testParameters → NO_COVERAGE

59

1.1
Location : testParameters
Killed by : none
replaced boolean return with false for com/jsql/util/SoapUtil::testParameters → NO_COVERAGE

2.2
Location : testParameters
Killed by : none
replaced boolean return with true for com/jsql/util/SoapUtil::testParameters → NO_COVERAGE

67

1.1
Location : testParameters
Killed by : none
replaced boolean return with true for com/jsql/util/SoapUtil::testParameters → NO_COVERAGE

72

1.1
Location : convertToDocument
Killed by : none
removed call to javax/xml/parsers/DocumentBuilderFactory::setAttribute → NO_COVERAGE

73

1.1
Location : convertToDocument
Killed by : none
removed call to javax/xml/parsers/DocumentBuilderFactory::setAttribute → NO_COVERAGE

74

1.1
Location : convertToDocument
Killed by : none
removed call to javax/xml/parsers/DocumentBuilderFactory::setAttribute → NO_COVERAGE

75

1.1
Location : convertToDocument
Killed by : none
removed call to javax/xml/parsers/DocumentBuilderFactory::setExpandEntityReferences → NO_COVERAGE

77

1.1
Location : convertToDocument
Killed by : none
replaced return value with null for com/jsql/util/SoapUtil::convertToDocument → NO_COVERAGE

82

1.1
Location : isTextNodeInjectable
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : isTextNodeInjectable
Killed by : none
negated conditional → NO_COVERAGE

84

1.1
Location : isTextNodeInjectable
Killed by : none
negated conditional → NO_COVERAGE

85

1.1
Location : isTextNodeInjectable
Killed by : none
negated conditional → NO_COVERAGE

86

1.1
Location : isTextNodeInjectable
Killed by : none
replaced boolean return with false for com/jsql/util/SoapUtil::isTextNodeInjectable → NO_COVERAGE

89

1.1
Location : isTextNodeInjectable
Killed by : none
removed call to com/jsql/util/SoapUtil::removeInjectionPoint → NO_COVERAGE

91

1.1
Location : isTextNodeInjectable
Killed by : none
removed call to org/w3c/dom/Node::setTextContent → NO_COVERAGE

92

1.1
Location : isTextNodeInjectable
Killed by : none
removed call to com/jsql/util/ParameterUtil::initRequest → NO_COVERAGE

98

1.1
Location : lambda$isTextNodeInjectable$1
Killed by : none
replaced return value with null for com/jsql/util/SoapUtil::lambda$isTextNodeInjectable$1 → NO_COVERAGE

99

1.1
Location : lambda$isTextNodeInjectable$2
Killed by : none
replaced return value with null for com/jsql/util/SoapUtil::lambda$isTextNodeInjectable$2 → NO_COVERAGE

100

1.1
Location : lambda$isTextNodeInjectable$3
Killed by : none
replaced return value with null for com/jsql/util/SoapUtil::lambda$isTextNodeInjectable$3 → NO_COVERAGE

102

1.1
Location : isTextNodeInjectable
Killed by : none
negated conditional → NO_COVERAGE

103

1.1
Location : isTextNodeInjectable
Killed by : none
replaced boolean return with false for com/jsql/util/SoapUtil::isTextNodeInjectable → NO_COVERAGE

105

1.1
Location : isTextNodeInjectable
Killed by : none
removed call to org/w3c/dom/Node::setTextContent → NO_COVERAGE

118

1.1
Location : isTextNodeInjectable
Killed by : none
replaced boolean return with true for com/jsql/util/SoapUtil::isTextNodeInjectable → NO_COVERAGE

123

1.1
Location : getNodeList
Killed by : none
negated conditional → NO_COVERAGE

134

1.1
Location : getNodeList
Killed by : none
replaced return value with null for com/jsql/util/SoapUtil::getNodeList → NO_COVERAGE

139

1.1
Location : removeInjectionPoint
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : removeInjectionPoint
Killed by : none
changed conditional boundary → NO_COVERAGE

141

1.1
Location : removeInjectionPoint
Killed by : none
negated conditional → NO_COVERAGE

142

1.1
Location : removeInjectionPoint
Killed by : none
removed call to com/jsql/util/SoapUtil::removeInjectionPoint → NO_COVERAGE

143

1.1
Location : removeInjectionPoint
Killed by : none
negated conditional → NO_COVERAGE

144

1.1
Location : removeInjectionPoint
Killed by : none
removed call to org/w3c/dom/Node::setTextContent → NO_COVERAGE

155

1.1
Location : convertDocumentToString
Killed by : none
removed call to javax/xml/transform/TransformerFactory::setAttribute → NO_COVERAGE

156

1.1
Location : convertDocumentToString
Killed by : none
removed call to javax/xml/transform/TransformerFactory::setAttribute → NO_COVERAGE

162

1.1
Location : convertDocumentToString
Killed by : none
removed call to javax/xml/transform/Transformer::transform → NO_COVERAGE

167

1.1
Location : convertDocumentToString
Killed by : none
replaced return value with "" for com/jsql/util/SoapUtil::convertDocumentToString → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.23.0