Apache Commons Text CVE-2022-42889 Fix for JMeter
Tags: performance, testing, java, security
Published: 2022-11-07 17:35:17


<!-- wp:paragraph -->
<p>After the <a href="https://qainsights.com/log4j-vulnerability-important-note-to-performance-engineers/" target="_blank" rel="noreferrer noopener">Log4Shell fiasco</a> last year, it is now time to apply the patch for <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-42889" target="_blank" rel="noreferrer noopener">CVE-2022-42889</a> to your Java ecosystem. In this blog post, we will see about CVE-2022-42889 specs and how to mitigate in your JMeter ecosystem. </p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>What is CVE-2022-42889?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>From the <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-42889" target="_blank" rel="noreferrer noopener">National Vulnerability Database</a>, the description is as follows:</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><em>Apache Commons Text performs variable interpolation, allowing properties to be dynamically evaluated and expanded. The standard format for interpolation is "${prefix:name}", where "prefix" is used to locate an instance of org.apache.commons.text.lookup.StringLookup that performs the interpolation. Starting with version 1.5 and continuing through 1.9, the set of default Lookup instances included interpolators that could result in arbitrary code execution or contact with remote servers. These lookups are: - "script" - execute expressions using the JVM script execution engine (javax.script) - "dns" - resolve dns records - "url" - load values from urls, including from remote servers Applications using the interpolation defaults in the affected versions may be vulnerable to remote code execution or unintentional contact with remote servers if untrusted configuration values are used. Users are recommended to upgrade to Apache Commons Text 1.10.0, which disables the problematic interpolators by default. </em></p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>What is Apache Commons?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Apache Commons is a collection of Java reusable components from the Apache Software Foundation. It consists of three parts:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li><a href="https://commons.apache.org/components.html">The Commons Proper</a>&nbsp;- A repository of reusable Java components</li><li><a href="https://commons.apache.org/sandbox.html">The Commons Sandbox</a>&nbsp;- A workspace for Java component development</li><li><a href="https://commons.apache.org/dormant.html">The Commons Dormant</a>&nbsp;- A repository of components that are now inactive</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Commonly used Java components from Apache Commons are CSV, IO, Net, Text, and more.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Apache Commons Text</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><a href="https://github.com/apache/commons-text" target="_blank" rel="noreferrer noopener">Apache Commons Text</a> is a library focused on algorithms working on strings. <a href="https://commons.apache.org/proper/commons-text/apidocs/index.html" target="_blank" rel="noreferrer noopener">Here</a> is the Java documentation page.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If you are a developer, you still use this library without your knowledge via the <a href="https://qainsights.com/docker-sbom/" target="_blank" rel="noreferrer noopener">software supply chain</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Dive into CVE-2022-48229</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>If your application uses the Apache Commons Text version between 1.5 - 1.9 (both inclusive), then the attacker can make use of the vulnerability in <code>StringSubstitutor</code> class. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Here is the sample snippet which I created using the above docs page. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Below code snippet (using Apache Commons Text 1.9) leverages the <code>StringSubstitutor</code> and interpolation where it prints the encoding and decoding string information by executing it as a string input.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>// Apache Commons Text 1.9

package org.qainsights;
import org.apache.commons.text.*;

public class Main {
    public static void main(String&#91;] args) {

    StringSubstitutor interp = StringSubstitutor.createInterpolator();

    String str = "Base64 Decoder ${base64Decoder:UUFJbnNpZ2h0cw==}\nBase64 Encoder ${base64Encoder:QAInsights}";
    String rep = interp.replace(str);

    System.out.println(rep);

    }
}</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>It may not look like a vulnerability for normal eyes, but attackers can leverage the string inputs of dns, script, and url functions.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Here are the default interpolators which use the string lookups as above:</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">final StringSubstitutor interpolator = StringSubstitutor.createInterpolator();
 final String text = interpolator.replace(
       "Base64 Decoder:        ${base64Decoder:SGVsbG9Xb3JsZCE=}\n"
     + "Base64 Encoder:        ${base64Encoder:HelloWorld!}\n"
     + "Java Constant:         ${const:java.awt.event.KeyEvent.VK_ESCAPE}\n"
     + "Date:                  ${date:yyyy-MM-dd}\n"
     + "Environment Variable:  ${env:USERNAME}\n"
     + "File Content:          ${file:UTF-8:src/test/resources/document.properties}\n"
     + "Java:                  ${java:version}\n"
     + "Localhost:             ${localhost:canonical-name}\n"
     + "Properties File:       ${properties:src/test/resources/document.properties::mykey}\n"
     + "Resource Bundle:       ${resourceBundle:org.apache.commons.text.example.testResourceBundleLookup:mykey}\n"
     + "System Property:       ${sys:user.dir}\n"
     + "URL Decoder:           ${urlDecoder:Hello%20World%21}\n"
     + "URL Encoder:           ${urlEncoder:Hello World!}\n"
     + "XML XPath:             ${xml:src/test/resources/document.xml:/root/path/to/node}\n");</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>Below are the extra lookups which are not included in Apache Commons Text 1.10:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>"dns"	dnsStringLookup()
"url"	urlStringLookup()
"script"	scriptStringLookup()</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Let us execute the <code>url</code> string lookup in version 1.9.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>package org.qainsights;
import org.apache.commons.text.*;

public class Main {
    public static void main(String&#91;] args) {

    StringSubstitutor interp = StringSubstitutor.createInterpolator();

    String str = "${url:UTF-8:https://example.com}";
    String rep = interp.replace(str);

    System.out.println(rep);

    }
}</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>The above snippet will display the HTML output of https://example.com.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Now, let us upgrade the Apache Commons Text to 1.10.0. The above code will display the output below. </p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>${url:UTF-8:https://example.com}</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Basically, version 1.10.0 will not process the string lookups of dns, script, and url by DEFAULT.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If you still want to make use of the dns, script, and url lookups, you need to enable them explicitly. Here is the sample code:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>// Enabling dns lookup in Apache Commons Text 1.10.0

package org.qainsights;
import org.apache.commons.text.*;
import org.apache.commons.text.lookup.StringLookup;
import org.apache.commons.text.lookup.StringLookupFactory;

import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String&#91;] args) {

    Map&lt;String, StringLookup&gt; lookupMap = new HashMap&lt;&gt;();
    lookupMap.put("dns", StringLookupFactory.INSTANCE.dnsStringLookup());

    StringLookup variableResolver = StringLookupFactory.INSTANCE.interpolatorStringLookup(lookupMap, null, false);

    System.out.println(new StringSubstitutor(variableResolver).replace("${dns:address|apache.org}"));

    }
}</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2>Mitigating it in Apache JMeter</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Now we are equipped with the knowledge of Apache Commons Text vulnerability. Let us go ahead with how to mitigate the CVE-2022-42889 in Apache JMeter.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>As you already know, Apache JMeter is a pure 100% Java performance testing tool which heavily relies on Apache Commons libraries. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>First step is to find the <code>commons-text-1.9.jar</code> in <code>JMETER_HOME\lib</code> folder and replace it with the <code>1.10.0</code> version by downloading and extracting it from https://commons.apache.org/proper/commons-text/download_text.cgi</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That's it. You are good to go. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Here is the <a href="https://github.com/QAInsights/cve-2022-42889-jmeter" target="_blank" rel="noreferrer noopener">automated script</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:buttons {"layout":{"type":"flex","justifyContent":"center"}} -->
<div class="wp-block-buttons"><!-- wp:button {"backgroundColor":"global-color-8","className":"is-style-fill"} -->
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-global-color-8-background-color has-background" href="https://github.com/QAInsights/cve-2022-42889-jmeter">GitHub Repo</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons -->

<!-- wp:heading -->
<h2>Conclusion</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Considering the CVSS of 9.8 for the CVE-2022-42889, it is highly recommended to patch your environment with the latest patch. You can use the above script to automate. Please let me know if you have any questions.</p>
<!-- /wp:paragraph -->