Get Data From XML File By Using cxXPath - checkmarx-ts/CxDOM-Types GitHub Wiki
For Java Programming Language, and other programming languages, there would be some XML files in the project.
A list of XML files:
- pom.xml
- web.xml
- struts.xml
- struts-config.xml
- *-validation.xml
- Info.plist
- faces-config.xml
You might need to get some information from the XML files by using CxQL. CxQL has cxXPath queries to support this feature.
Here is an example pom.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>actuator-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>actuator-demo</name>
<description>Spring Boot Actuator Demo Project</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.12</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-text -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.9</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Here is the source code of the query Find_Config_via_Xml, you shall override the one Java/Cx/General/Find_Config_via_Xml:
// Find configuration information from XML files.
// First parameter is the file pattern to capture the XML files, for example "*pom.xml".
// Second parameter is the XPath pattern to find the tag or attribute from the XML files.
if (param.Length == 2){
string files = param[0] as string;
string query = param[1] as string;
if(!string.IsNullOrEmpty(query)){
foreach (CxXmlDoc doc in cxXPath.GetXmlFiles(files)){
XPathNodeIterator nodeIterator = doc.CreateNavigator().Select(query);
while (nodeIterator.MoveNext()){
result.Add(cxXPath.CreateXmlNode(nodeIterator.Current.Clone(), doc, 2, false));
}
}
}
}
In order to get version tag for groupId "org.apache.commons" and artificatId "commons-text", we should construct the xPath like this:
/*[local-name()='project']/*[local-name()='dependencies']/*[local-name()='dependency'][*[local-name()='groupId'] = 'org.apache.commons' and *[local-name()='artifactId'] = 'commons-text']/*[local-name()='version']
How to construct the XPath, we can use the following query:
string groupId = "org.apache.commons";
string artifactId = "commons-text";
Func<string, string> ln = (name) => $"*[local-name() = '{name}']";
Func<string, string> elem = (name) => "/" + ln(name);
string dependencyVersion = elem("project") + elem("dependencies") + elem("dependency") +
"[" + ln("groupId") + " = '" + groupId + "' and " + ln("artifactId") + " = '" + artifactId + "'" + "]" + elem("version");
Please note that we can use the and operator to combine the conditions when filter the dependency tags. Then we have the version tag which is a child of dependency tag.
Notice: If you copy the above code to CxAudit, CxAudit would remove the $ sign, you have to add it manually.
Run the following CxQL query for a project which contains the above pom.xml file will return a CxList object with the version tag:
string groupId = "org.apache.commons";
string artifactId = "commons-text";
Func<string, string> ln = (name) => $"*[local-name() = '{name}']";
Func<string, string> elem = (name) => "/" + ln(name);
string dependencyVersion = elem("project") + elem("dependencies") + elem("dependency") +
"[" + ln("groupId") + " = '" + groupId + "' and " + ln("artifactId") + " = '" + artifactId + "'" + "]" + elem("version");
CxList version = Find_Config_via_Xml("*pom.xml", dependencyVersion);
result = version;
Notice: If you copy the above code to CxAudit, CxAudit would remove the $ sign, you have to add it manually.
The XML file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">10006_HardCodedSensitiveInformationInResourceFile</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="password">admin23456</string>
<string name="secret">admin23456</string>
<string name="himitsu">admin23456</string>
<string name="pass">admin23456</string>
<string name="pass2">input password</string>
<string name="hash1">50764755a9cd0f12619ec1bbc7f93eb2</string>
<string name="hash2">50764755a9cd0f12619ec1bbc7f93eb212345678</string>
<string name="hash3">50764755a9cd0f12619ec1bbc7f93eb250764755a9cd0f12619ec1bbc7f93eb2</string>
</resources>
The XPath
/*[local-name() ='resources']/*[local-name() ='string']/@name
The CxQL query
Func<string, string> attribute = (name) => $"/@{name}";
Func<string, string> ln = (name) => $"*[local-name() = '{name}']";
Func<string, string> elem = (name) => "/" + ln(name);
string attributePath = elem("resources") + elem("string") + attribute("name");
result = Find_Config_via_Xml("*.xml", attributePath);
Notice: If you copy the above code to CxAudit, CxAudit would remove the $ sign, you have to add it manually.
You can use the following CxQL query to have a look at your tag value or attribute value
foreach (CxList node in result) {
CxXmlNode finalXmlNode = node.GetFirstGraph() as CxXmlNode;
string nodeValue = finalXmlNode.Value;
cxLog.WriteDebugMessage(nodeValue);
}