CVE-2022-42889, commonly called Text4Shell, is a critical vulnerability associated with Apache Commons Text’s string interpolation functionality. It became particularly notable because certain default string lookups available in Apache Commons Text versions 1.5 through 1.9 could perform operations far more powerful than ordinary text replacement, including script evaluation, DNS resolution, and retrieval of data from URLs.
Under the wrong application design, attacker-controlled text could therefore cross an important trust boundary: instead of remaining passive data, portions of that text could be interpreted as instructions by Apache Commons Text.
The National Vulnerability Database assigns CVE-2022-42889 a CVSS 3.1 base score of 9.8 Critical and identifies the weakness as CWE-94, Improper Control of Generation of Code. The affected Apache package range recorded by NVD is Commons Text 1.5 through versions earlier than 1.10.0. (National Vulnerability Database)
But that severity rating needs context.
Installing commons-text-1.9.jar yok değil automatically make every Java application remotely exploitable. Apache explicitly states that software containing a vulnerable Commons Text version is likely not affected unless it actually uses the relevant StringSubstitutor functionality and allows untrusted input to reach it without appropriate validation. (Apache Commons)
That distinction is the most important thing to understand about Text4Shell.
What Is CVE-2022-42889 Text4Shell?
Apache Commons Text is a Java library providing utilities for text processing, including escaping strings, similarity calculations, placeholder substitution, and related operations.
One of those capabilities is variable interpolation through the StringSubstitutor API.
A simple interpolation operation conceptually looks like this:
Hello ${name}
An application can associate isim with a value such as:
Alice
and produce:
Hello Alice
That alone is not particularly dangerous.
The security issue becomes more interesting because Commons Text also supports prefixed lookups:
${prefix:value}
Here, the prefix does not simply identify a variable. It can select a StringLookup implementation capable of performing an operation.
According to the CVE description, the affected default interpolation configuration included three particularly important lookups:
| Lookup | Intended behavior | Security implication |
|---|---|---|
script | Executes an expression through the JVM scripting API | Potential arbitrary code execution |
dns | Performs DNS resolution | Network interaction / possible information leakage |
url | Loads content from a URL | Server-side outbound network access |
These lookups were included among the default interpolation capabilities in Commons Text 1.5 through 1.9. Apache Commons Text 1.10.0 changed that default behavior so the dangerous script, dnsve url lookups were no longer enabled automatically. (National Vulnerability Database)
This is the design decision at the center of CVE-2022-42889.
How Apache Commons Text String Interpolation Works
The API most closely associated with Text4Shell is:
StringSubstitutor.createInterpolator()
Apache’s current documentation demonstrates the API with lookups capable of reading environment variables, Java platform information, dates, encoded data, and other sources. It also explicitly notes that the list of lookups returned by createInterpolator() changed starting with Commons Text 1.10.0. (Apache Commons)
Consider an application performing something conceptually similar to:
StringSubstitutor interpolator =
StringSubstitutor.createInterpolator();
String result = interpolator.replace(userInput);
This is the key security boundary.
Eğer userInput is attacker-controlled and the interpolator exposes functionality that performs actions rather than simple substitution, an attacker may be able to select those actions through specially formatted expressions.
A harmless conceptual example would be:
${script:javascript:1+1}
The point is not the arithmetic result. The important issue is that what appears to be ordinary text is being handed to a script interpreter.
GitHub Security Lab, which independently reported the issue, specifically identified data flowing into StringSubstitutor.replace() veya replaceIn() while the default interpolator was enabled as the dangerous pattern. Its research demonstrated that the ScriptStringLookup path could ultimately turn an attacker-controlled interpolation string into arbitrary code execution. (GitHub Security Lab)
The vulnerable data flow can therefore be summarized as:
Untrusted Input
↓
Application
↓
StringSubstitutor.createInterpolator()
↓
replace() / replaceIn()
↓
${prefix:value}
↓
StringLookup
↓
script / dns / url
↓
Code Execution or Network Activity
This is fundamentally an injection problem caused by treating attacker-controlled data as executable interpolation syntax.

What Are the Actual Text4Shell RCE Conditions?
The phrase “Apache Commons Text RCE” can be misleading if interpreted as meaning that simply having Commons Text installed gives an attacker remote code execution.
It does not.
A realistic Text4Shell RCE requires several conditions to line up.
1. The application must use an affected Commons Text configuration
NVD identifies Commons Text versions 1.5 through 1.9 as affected by the dangerous default lookup configuration. Version 1.10.0 changed the defaults. (National Vulnerability Database)
Finding:
commons-text-1.9.jar
is therefore a reason to investigate.
It is not proof of exploitability.
2. The application must actually invoke the interpolation functionality
Apache’s own security guidance emphasizes this point.
Applications merely depending on Commons Text are not necessarily exposed. The vulnerable application needs to use StringSubstitutor, particularly in a way that makes the dangerous interpolation behavior reachable. (Apache Commons)
Source-code review should therefore look for patterns such as:
StringSubstitutor.createInterpolator()
followed by:
replace(...)
or:
replaceIn(...)
The library version identifies potential exposure.
Bu data flow identifies actual risk.
3. Attacker-controlled data must reach the substitution operation
This is probably the most important exploitation requirement.
Suppose an application does this:
String template =
loadTrustedTemplateFromApplicationResources();
String result = interpolator.replace(template);
If the template is fully trusted and cannot be influenced by an attacker, the presence of a vulnerable version alone does not provide a remote injection path.
Now consider:
String template =
request.getParameter("template");
String result = interpolator.replace(template);
The security situation is completely different.
The attacker controls text that will be interpreted by StringSubstitutor.
Potential sources include application-specific inputs such as:
HTTP parameters
JSON request bodies
user-controlled templates
configuration interfaces
uploaded text files
message queues
database values controlled by users
administrative configuration
API fields
Whether any of these become exploitable depends entirely on how the application moves them into StringSubstitutor.
Apache specifically warns about the condition where untrusted input reaches this API without proper validation or sanitization. (Apache Commons)
4. A Compatible Script Engine Must Be Available for the Script RCE Path
Bu script lookup operates through Java’s scripting infrastructure, javax.script. The NVD description explicitly identifies this mechanism. (National Vulnerability Database)
That detail matters because script execution depends on a suitable scripting engine being present.
Historically, Java included the Nashorn JavaScript engine. Oracle documents that Nashorn was deprecated for removal in Java 11 and removed from the JDK in Java 15. (Oracle Documentation)
Consequently, a Java 15+ runtime without an additional compatible scripting engine may not reproduce the same JavaScript-based execution path that worked in environments where Nashorn was available.
But this should değil be treated as a mitigation strategy.
Applications may package alternative scripting engines or explicitly provide other javax.script implementations. Runtime differences therefore change exploitability rather than eliminating the underlying unsafe design.
The correct question is not:
“Are we running Java 17?”
It is:
“Can attacker-controlled interpolation syntax reach a lookup capable of executing code in this application’s actual runtime?”
That requires inspecting both the application and its dependency/runtime environment.
The Three Dangerous Text4Shell Lookups
Text4Shell is often discussed entirely as an RCE vulnerability, but understanding all three affected lookups gives defenders a much more accurate model.
script
Bu script lookup can evaluate expressions using a JVM script engine.
Conceptually:
${script:<language>:<expression>}
If the application accepts attacker-controlled interpolation strings and a compatible script engine is available, execution can move beyond string transformation into arbitrary program behavior.
GitHub Security Lab specifically identified this lookup as the route to arbitrary code execution. (GitHub Security Lab)
dns
Bu dns lookup resolves DNS records.
An attacker who can inject a dynamically chosen hostname may therefore cause the affected Java process to perform DNS queries.
This can matter for several reasons.
At minimum, DNS requests can provide an externally observable signal that interpolation occurred. In some application contexts, attacker-controlled DNS lookups may also contribute to blind vulnerability confirmation or information leakage techniques.
NVD explicitly identifies DNS resolution as one of the network-capable default lookups involved in CVE-2022-42889. (National Vulnerability Database)
url
Bu url lookup can retrieve values from URLs.
Current Apache documentation still exposes URL lookup functionality for applications that intentionally configure it, but it is no longer part of the default safe lookup set. (Apache Commons)
If untrusted interpolation can control such a lookup, the vulnerable server may make outbound requests selected by an attacker.
This potentially turns what appears to be a string-processing feature into a server-side network primitive.
The exact impact depends on network access, protocols, application behavior, response handling, and runtime configuration.
Why Apache Commons Text 1.10.0 Fixes the Dangerous Default
The Text4Shell fix is particularly interesting because Apache did not remove interpolation functionality altogether.
Instead, Commons Text moved toward a safer default configuration.
Apache explains that network-accessing or code-executing interpolators were intentionally available features, but allowing them automatically increased the consequences when applications mistakenly passed untrusted input into interpolation. The project therefore changed the defaults to make such mistakes less dangerous. (Apache Commons)
Current Apache Commons Text documentation makes this policy explicit:
lookups capable of executing code and lookups capable of contacting remote servers are not included in the default set.
The current documentation specifically identifies SCRIPT, URLve DNS as examples. (Apache Commons)
This is a good example of secure-by-default API design.
Before the change, an application developer could unknowingly inherit powerful behaviors simply by constructing the general-purpose interpolator.
After the change, developers who genuinely require those capabilities need to make a more explicit configuration decision.
Does Commons Text 1.10.0 Make Unsafe Input Safe?
No.
Upgrading is essential, but treating it as a replacement for input validation would miss the larger lesson of CVE-2022-42889.
Apache explicitly recommends both upgrading and properly validating or sanitizing untrusted input. (Apache Commons)
There is another important reason.
The dangerous lookup implementations still exist.
Apache’s current API documentation explains that applications can intentionally add dns, scriptveya url lookups programmatically or configure lookup behavior through the org.apache.commons.text.lookup.StringLookupFactory.defaultStringLookups system property. (Apache Commons)
Therefore, this code deserves scrutiny even on newer Commons Text releases:
Map<String, StringLookup> lookups = new HashMap<>();
lookups.put(
"script",
StringLookupFactory.INSTANCE.scriptStringLookup()
);
A modern Commons Text dependency combined with a developer explicitly recreating dangerous behavior can still create an injection problem.
The vulnerability fix made the library safer by default.
It did not change the fundamental rule:
Never give untrusted data access to an interpreter with capabilities the attacker should not control.
Text4Shell vs Log4Shell
CVE-2022-42889 appeared less than a year after the disclosure of Log4Shell, CVE-2021-44228, and the similarity of the names naturally created comparisons.
Technically, however, the exposure models are significantly different.
Apache itself specifically warns against assuming that Text4Shell has the same widespread exploitation characteristics as Log4Shell. (Apache Commons)
| Characteristic | Text4Shell | Log4Shell |
|---|---|---|
| CVE | CVE-2022-42889 | CVE-2021-44228 |
| Bileşen | Apache Commons Text | Apache Log4j |
| Core feature | String interpolation | Logging/message lookup behavior |
| Dangerous input path | Must reach StringSubstitutor | Untrusted strings commonly reach logging |
| Exploitation prevalence | Application-specific | Much broader reachable attack surface |
| Ana ders | Don’t evaluate untrusted templates | Don’t embed active lookup semantics in untrusted logging paths |
The critical difference is reachability.
Applications routinely log untrusted values:
User-Agent
URLs
headers
request parameters
authentication events
error strings
That made the vulnerable Log4j behavior reachable from many externally controlled surfaces.
By comparison, Commons Text’s StringSubstitutor is explicitly an interpolation API. An application developer normally needs to invoke it intentionally.
Apache noted that it was not aware, at the time of its advisory, of applications actually passing untrusted input into the substitutor in the manner required for exploitation. (Apache Commons)
So although both vulnerabilities involved powerful lookup behavior hidden behind ${...}-style syntax, their real-world exposure models were very different.

Why CVSS 9.8 Does Not Mean Every Deployment Is Critical
NVD currently records CVE-2022-42889 with the following CVSS 3.1 vector:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
and a 9,8 Kritik base score. (National Vulnerability Database)
That rating describes the severity of a successfully exposed vulnerable path.
It does not prove that such a path exists in every application.
This illustrates an important vulnerability-management principle:
Severity ≠ Reachability
A more useful organizational risk model is:
Risk =
Vulnerable Component
× Vulnerable API Usage
× Attacker-Controlled Data Flow
× Required Runtime Capability
× Network Reachability
× Business Impact
A software composition analysis tool may identify:
org.apache.commons:commons-text:1.9
That is valuable.
But a security engineer still needs to answer:
Is StringSubstitutor used?
Does the application use createInterpolator()?
Can attacker-controlled text reach replace()?
Are dangerous lookups available?
Is a script engine present?
What privileges does the JVM possess?
That is the difference between dependency detection ve vulnerability validation.
How to Check Whether Your Application Uses a Vulnerable Commons Text Version
For Maven projects, dependency inspection can start with:
mvn dependency:tree
Then look for:
org.apache.commons:commons-text
A more focused command is:
mvn dependency:tree -Dincludes=org.apache.commons:commons-text
For Gradle:
./gradlew dependencies
or:
./gradlew dependencyInsight \
--dependency commons-text
Also inspect packaged applications because Commons Text may arrive transitively rather than being explicitly declared in your primary build configuration.
The affected Apache dependency range identified by NVD and GitHub is:
>= 1.5
< 1.10.0
ile 1.10.0 containing the secure-default change. (National Vulnerability Database)
Source-Code Review for CVE-2022-42889
Dependency scanning should be followed by source and data-flow analysis.
Search for:
StringSubstitutor
and particularly:
createInterpolator()
Then inspect calls to:
replace()
replaceIn()
GitHub Security Lab specifically identified untrusted data reaching these methods as the dangerous path. (GitHub Security Lab)
A high-risk pattern looks conceptually like:
String userSuppliedTemplate =
request.getParameter("template");
StringSubstitutor substitutor =
StringSubstitutor.createInterpolator();
String output =
substitutor.replace(userSuppliedTemplate);
The security question is not simply whether this code exists.
You must trace where userSuppliedTemplate originates.
The same operation may be acceptable with an immutable application-owned template and dangerous with a value supplied through a public API.
A Safer Design
Whenever possible, applications should define exactly which variables users are allowed to influence rather than exposing a generic expression interpreter.
Örneğin:
Map<String, String> values = new HashMap<>();
values.put("customerName", validatedCustomerName);
values.put("orderId", validatedOrderId);
StringSubstitutor substitutor =
new StringSubstitutor(values);
String result =
substitutor.replace(trustedTemplate);
The application now controls both the template and the available values.
This creates a much narrower trust boundary than exposing a generic interpolator capable of selecting arbitrary lookup implementations.
The broader principle is:
Allowlist intended transformations.
Do not blocklist dangerous expressions.
Blocking strings such as:
${script:
can provide a secondary signal, but it is much weaker than designing the application so attackers never control the interpreted expression grammar in the first place.
Detecting Potential Text4Shell Exploitation
Detection should be based on the underlying execution path rather than expecting one universal payload.
Search Application Inputs for Interpolation Syntax
Where relevant, investigate unexpected attacker-controlled strings containing patterns such as:
${
or historically significant lookup prefixes such as:
script:
dns:
url:
This is best treated as a hunting indicator, not proof of exploitation.
Legitimate applications may themselves support interpolation.
Monitor DNS Activity from Java Processes
Because vulnerable interpolation could trigger DNS lookups, unexpected DNS requests originating from Java application servers can provide useful telemetry.
Pay particular attention when an internet-facing application unexpectedly resolves unusual, newly seen, or attacker-controlled domains shortly after receiving requests containing interpolation-like syntax. The relevance of this telemetry follows directly from the DNS lookup behavior documented for CVE-2022-42889. (National Vulnerability Database)
Monitor Unexpected Outbound Connections
The vulnerable URL lookup could cause the Java process to access remote resources. (National Vulnerability Database)
Outbound network monitoring should therefore correlate:
incoming request
↓
Java application
↓
unexpected DNS resolution
↓
unexpected outbound connection
Correlating events is much stronger than searching for one static string.
Monitor Child Processes Spawned by Java
For environments where script evaluation can reach operating-system functionality, suspicious child-process creation from a Java server is a high-value behavioral signal.
Examples of processes deserving investigation include unexpected shell interpreters, command utilities, downloaders, or reconnaissance programs started by:
java
javaw
application server JVMs
The important indicator is not the process name alone.
It is the context:
Internet Request
↓
Java Service
↓
Unexpected Child Process
↓
Network / File / Credential Activity
How to Mitigate CVE-2022-42889
The primary remediation is straightforward.
Upgrade Apache Commons Text from vulnerable versions to at least 1.10.0 or later.
Apache and NVD both identify 1.10.0 as the release that disables the dangerous interpolators by default. (Apache Commons)
Organizations should normally move to an appropriately supported current Commons Text version rather than deliberately freezing on the minimum fixed release, subject to compatibility testing.
But the dependency upgrade should be accompanied by application review.
Remove Untrusted Template Evaluation
Bak:
StringSubstitutor.createInterpolator()
combined with untrusted strings passed into:
replace()
replaceIn()
Do not treat arbitrary user strings as interpolation programs.
Review Explicit Lookup Configuration
On newer Commons Text releases, inspect whether the application deliberately restores:
SCRIPT
DNS
URL
lookups.
Apache’s current documentation confirms these capabilities can still be explicitly configured even though they are no longer part of the default set. (Apache Commons)
Restrict JVM Privileges
A compromised application should not automatically imply compromise of the entire host or cloud environment.
Run Java services with the minimum filesystem, operating-system, credential, and cloud permissions required.
Restrict Outbound Network Access
Application workloads rarely need unrestricted egress.
Where operationally possible, restrict connections from application servers to approved destinations.
This reduces the impact of URL-based network access, DNS abuse, payload retrieval, and post-exploitation command-and-control.
Protect Secrets
Do not unnecessarily expose credentials through:
environment variables
configuration files
cloud instance metadata
mounted secrets
application directories
to application processes.
The less authority the compromised JVM possesses, the smaller the eventual blast radius.
Why Text4Shell Still Matters
CVE-2022-42889 is valuable to study even years after disclosure because the underlying problem extends far beyond one Apache library.
Modern applications increasingly embed miniature interpreters:
template engines
expression languages
workflow systems
configuration languages
query builders
automation platforms
AI agent tools
policy engines
scripting environments
Whenever a system converts text into actions, a trust boundary appears.
The pattern is:
Untrusted Data
↓
Parser
↓
Interpreter
↓
Capability
If attacker-controlled input can cross all four stages, the difference between “data” and “code” disappears.
Text4Shell is therefore not merely an old Java dependency issue.
It is an example of a broader architectural security rule:
The danger of an interpreter is determined not only by what syntax it accepts, but by what capabilities that syntax can reach.
Text4Shell and Modern Security Testing
Traditional dependency scanners are very good at answering:
Is commons-text 1.9 present?
That is only the first part of the problem.
A deeper security assessment should determine:
Is the vulnerable class loaded?
↓
Is StringSubstitutor actually used?
↓
Does the application create the interpolator?
↓
Can untrusted input reach it?
↓
Which lookups are enabled?
↓
Does the runtime contain a script engine?
↓
Can that JVM perform dangerous actions?
↓
Can an external attacker reach the vulnerable input?
This type of reasoning matters for Text4Shell because Apache itself emphasizes that simply using software containing an old Commons Text release does not imply exploitable exposure. (Apache Commons)
The same distinction increasingly matters across modern application security:
component vulnerability → reachable code → controllable data flow → security impact.
Scanning identifies candidates.
Validation determines whether they matter.
Frequently Asked Questions About CVE-2022-42889
What is CVE-2022-42889?
CVE-2022-42889 is an Apache Commons Text vulnerability involving unsafe default string interpolation capabilities. Commons Text versions 1.5 through 1.9 included script, dnsve url lookups in the relevant default interpolation configuration, potentially enabling code execution or remote network interaction when untrusted input was evaluated. (National Vulnerability Database)
What is Text4Shell?
Text4Shell is the commonly used name for CVE-2022-42889, referring to the Apache Commons Text interpolation vulnerability.
Is Text4Shell a remote code execution vulnerability?
It can produce RCE, but only when the application’s implementation exposes the necessary execution path.
GitHub Security Lab demonstrated that untrusted input reaching StringSubstitutor.replace() veya replaceIn() through the vulnerable interpolator could reach script evaluation and potentially arbitrary code execution. (GitHub Security Lab)
Which versions of Apache Commons Text are affected?
The CVE and GitHub advisory identify:
Apache Commons Text 1.5 through 1.9
as affected, with:
Apache Commons Text 1.10.0
containing the secure-default change. (National Vulnerability Database)
Is Apache Commons Text 1.9 automatically exploitable?
No.
Apache explicitly states that merely depending on a Commons Text version prior to 1.10.0 does not mean the application is exploitable. The application must use the relevant substitution API and allow untrusted input into that interpolation path. (Apache Commons)
Does Text4Shell work on every Java version?
No single script-based RCE path should be assumed to work identically across every runtime.
Bu script lookup relies on the JVM scripting infrastructure. Nashorn, the JavaScript engine historically bundled with the JDK, was removed starting with JDK 15. Other scripting engines can still be supplied separately, so Java 15+ should not be treated as a security fix for Text4Shell. (National Vulnerability Database)
Is Text4Shell the same as Log4Shell?
No.
Both involve dangerous interpolation concepts, but their exposure models are different. Apache notes that Log4Shell commonly processed attacker-controlled logging data, whereas Commons Text substitution must normally be explicitly invoked by the application. That makes accidental attacker reachability significantly less universal for Text4Shell. (Apache Commons)
How do you fix CVE-2022-42889?
Upgrade Commons Text to 1.10.0 or later, review all uses of StringSubstitutor, prevent untrusted input from becoming interpolation syntax, and verify that dangerous script, dnsve url lookups have not been explicitly restored. (Apache Commons)
Son Çıkarım
CVE-2022-42889 Text4Shell is a critical Apache Commons Text vulnerability, but understanding its exploitability requires more than reading its 9.8 CVSS score.
The dangerous chain is more accurately represented as:
Apache Commons Text 1.5–1.9
↓
StringSubstitutor interpolation
↓
Attacker-controlled input
↓
Dangerous lookup selected
↓
Required runtime capability available
↓
Code execution or outbound network activity
Remove any one of those conditions and the practical result may change dramatically.
That is why defenders should avoid both extremes.
It would be wrong to dismiss CVE-2022-42889 simply because it is not Log4Shell.
It would also be wrong to assume that every application containing Commons Text 1.9 offers an unauthenticated internet-facing RCE endpoint.
The correct response is to patch first, then validate reachability.
Upgrade to Commons Text 1.10.0 or later, audit StringSubstitutor usage, trace untrusted data into interpolation operations, verify which lookup capabilities exist at runtime, and monitor Java applications for unexpected process execution or outbound activity.
The lasting lesson from Text4Shell is larger than Apache Commons Text itself:
data becomes dangerous when application infrastructure silently gives it the authority to behave like code. (Apache Commons)

