SoapUtil.java

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
Location : testParameters
Killed by : none
negated conditional → NO_COVERAGE

44

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

48

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

49

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

55

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

62

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

69

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

70

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

71

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

72

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

76

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

83

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

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

87

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

89

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

90

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

92

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

94

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

96

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

98

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

104

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

105

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

108

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

109

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

125

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

132

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

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

136

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

138

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

139

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

140

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

152

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

153

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

160

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.16.1