CVE-2022-42889, nicknamed Text4Shell, is a remote code execution vulnerability in Apache Commons Text, rated CVSS v3.1 9.8 (Critical) by NVD. It stems from the library's string-interpolation feature: certain default lookups could evaluate script, DNS, or URL expressions embedded in input. Where an application fed untrusted data into the vulnerable interpolation methods, an attacker could execute arbitrary code. The "4Shell" name drew inevitable Log4Shell comparisons — but as security teams quickly clarified, the practical exploitability was meaningfully narrower.
Timeline and impact
The issue was reported to the Apache Commons project and became public around mid-October 2022, with the fixed release available shortly after. The initial wave of coverage treated it as "the next Log4Shell," which prompted a firm round of clarification from responders: unlike Log4Shell, where the dangerous lookup was reachable through routinely logged data, Text4Shell only triggers when an application explicitly passes attacker-controlled input into StringSubstitutor interpolation (or the related StringLookupFactory interpolator). That is a real and dangerous pattern, but far less common than "log any user-supplied string." The net effect was a critical-severity library flaw with a comparatively limited population of genuinely exploitable applications — and a useful lesson in matching panic to actual reachability.
It is worth being precise about why the Log4Shell analogy broke down, because it drove a lot of wasted effort. Log4Shell (CVE-2021-44228) was so devastating because logging is pervasive and implicit: developers log request headers, usernames, and user agents everywhere, so attacker-controlled strings reached the vulnerable JNDI lookup in the normal course of operation, often without any code being written to invoke it. Text4Shell has no such ambient trigger. An application has to call an interpolating method on untrusted input on purpose, and the script prefix additionally needs a script engine present on the classpath to reach full code execution. Several prominent responders publicly urged teams to stop calling it "4Shell" at all, precisely because the name implied a blast radius the bug did not have. The right response was calibrated: patch the library, but prioritize by whether the dangerous data flow actually exists.
Technical root cause
Commons Text provides StringSubstitutor for variable interpolation. The syntax is ${prefix:name}, where the prefix selects a lookup that resolves name. Many of these lookups are harmless (${env:HOME}, ${sys:user.dir}). The problem is that the default interpolator set also enabled three dangerous prefixes:
script— evaluates an expression through the JVM script engine (for example, JavaScript via Nashorn on suitable JDKs).url— fetches content from a URL.dns— resolves a DNS name.
If an application called an interpolating method on attacker-controlled input, a payload like the following triggered code execution:
// Vulnerable: untrusted input flows into interpolation
StringSubstitutor interpolator = StringSubstitutor.createInterpolator();
String result = interpolator.replace(untrustedInput);
// Attacker-supplied value:
// ${script:javascript:java.lang.Runtime.getRuntime().exec('touch /tmp/pwned')}
When replace() processes that string, the script lookup hands the JavaScript to a script engine, which invokes Runtime.exec. The url and dns prefixes similarly enable server-side request forgery and out-of-band interaction even where full code execution is not available. The critical qualifier — and the reason Text4Shell was less universal than Log4Shell — is that this only happens if the application deliberately interpolates untrusted input; simply having Commons Text on the classpath is not sufficient.
How to detect if you are affected
- Version check. The vulnerable range is Apache Commons Text 1.5 through 1.9; the fix is in 1.10.0. Inspect
commons-textin your dependency tree, including transitive pulls, since it is a common indirect dependency of larger libraries. - Trace the data flow. Beyond presence, determine whether any code path passes externally-controlled input into
StringSubstitutorinterpolation orcreateInterpolator()-based lookups. That is what separates exploitable from merely present. - Test carefully in a lab, using the
url/dnsprefixes for safe out-of-band confirmation rather than livescriptpayloads.
Version presence is quick to find; reachability is the harder half. Safeguard's software composition analysis pins commons-text versions across direct and transitive dependencies so you at least know every place it lives.
Remediation and patched versions
- Upgrade to Commons Text 1.10.0 or later. The fix disables the
script,dns, andurlinterpolators from the default set, so they are opt-in rather than active by default. - Rebuild artifacts and images that bundle the library — a patched version in your repo is inert until the artifact is rebuilt. Safeguard's container security scanning flags a vulnerable
commons-textinside image layers. - Audit call sites as defense in depth: never pass untrusted input to
StringSubstitutor.createInterpolator()-based interpolation, even on patched versions. - Re-scan after upgrade to confirm no transitive path still resolves an old version.
How Safeguard surfaces and auto-fixes Text4Shell
Text4Shell is the ideal case for reachability-aware prioritization, because the gap between "we have the dependency" and "we are exploitable" is enormous. Safeguard resolves your full dependency graph so a transitively-pulled commons-text is never invisible, and Griffin AI reasons about whether untrusted input can actually reach the vulnerable interpolation path — so you can down-rank the many apps that merely carry the library and focus on the few that genuinely expose it. Findings still carry CISA KEV and EPSS context so you are never guessing about real-world exploitation trends.
When a safe upgrade is available, automated fix pull requests raise the bump to 1.10.0 across your services and run your test suite, turning a critical-severity library advisory into a reviewed merge. And because early Text4Shell response was dominated by hype, our platform comparison shows how prioritization that weighs reachability keeps a team from burning a sprint on a flaw that, for most of its apps, was never reachable in the first place.
Text4Shell's real lesson was proportionality: severe on paper, narrow in practice, and only distinguishable with dependency-graph plus data-flow context.
Get started at app.safeguard.sh/register, or read the docs at docs.safeguard.sh.