CVE-2021-30640 is an authentication-weakness flaw in the **JNDIRealm** component of Apache Tomcat.
CVE-2021-30640 is an authentication-weakness flaw in the JNDIRealm component of Apache Tomcat. When Tomcat is configured to authenticate users against an LDAP directory via JNDIRealm, an attacker can craft username variations (case changes, encoding tricks) that the LDAP backend treats as the same principal but the LockOut Realm treats as distinct. This lets an attacker retry credentials without triggering account lockout, and in some edge cases authenticate with a mangled username the application doesn't expect. Affected versions: 9.0.0.M1–9.0.45, 10.0.0.M1–10.0.5, 8.5.0–8.5.65. Fixed in 9.0.46, 10.0.6, 8.5.66.
The NVD rates this 6.5 MEDIUM (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N), but that overstates real-world risk considerably. Apache's own advisory rates it Low. The CVSS vector's AC:H acknowledges the attack is hard to pull off, but the score doesn't capture the most important friction: JNDIRealm is a *non-default, niche configuration*. The vast majority of Tomcat deployments use MemoryRealm, DataSourceRealm, UserDatabaseRealm, or delegate auth to the app layer entirely. The vulnerability also doesn't grant code execution or data access — it weakens lockout enforcement and allows username-variant authentication. After five years, no public PoC exists, no exploitation has been observed, and it's absent from the CISA KEV catalog. Tenable's own VPR of 3.5 (Low) agrees with a sharp downgrade.
4 steps from start to impact.
Identify JNDI Realm configuration
<Realm className="org.apache.catalina.realm.JNDIRealm" .../> in server.xml or context.xml. Without this, the vulnerability is completely inapplicable.- Target Tomcat uses JNDIRealm (non-default)
- Authentication endpoint is network-reachable
- Most Tomcat deployments use UserDatabaseRealm, DataSourceRealm, or app-layer auth — JNDIRealm is a minority config
- Attacker has no reliable way to fingerprint Realm type remotely without trial-and-error
Craft username variations
ConcurrentHashMap treats as a distinct key. This requires knowledge of a valid username on the system.- Knowledge of at least one valid username
- Understanding of the LDAP directory's normalization behavior
- Requires reconnaissance to identify valid usernames
- Different LDAP implementations (AD, OpenLDAP, 389DS) handle normalization differently, making the attack non-generic
AccessLogValve would show attempts with unusual username encodings, but most teams don't alert on this.Bypass LockOut Realm counters
- LockOut Realm is configured (another non-default, opt-in feature)
- Password is guessable or known from another breach
- If the password is strong, unlimited brute-force attempts still won't succeed
- Many enterprise Tomcat deployments front-end auth with SSO/IdP, making Tomcat-level lockout irrelevant
- Rate limiting at WAF or reverse proxy layer independently blocks brute-force
Achieve authenticated access
- Successful password guess
- Application behind Tomcat has sensitive functionality accessible to the compromised user
- Most sensitive Tomcat-hosted apps (Jenkins, Nexus, etc.) have their own auth layer independent of Tomcat Realms
- MFA at the application or IdP layer blocks credential-only access
The supporting signals.
| In-the-Wild Exploitation | None observed. No confirmed campaigns, no CISA KEV listing. Five years post-disclosure with zero reported exploitation. |
|---|---|
| Proof of Concept | None public. No PoC repositories on GitHub, no Metasploit/Nuclei module, no ExploitDB entry. The attack is conceptual. |
| EPSS Score | ~0.10 (10%), 95th percentile per Rapid7. Elevated percentile reflects Tomcat's popularity, not this specific bug's exploitability. |
| CISA KEV Status | Not listed. No evidence of active exploitation warranting KEV inclusion. |
| CVSS Vector | CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N — Network-accessible but High complexity. Integrity-High reflects lockout bypass; Confidentiality-Low; no Availability impact. |
| Vendor Severity | Apache Foundation rates this Low. NVD rates it 6.5 Medium. Tenable VPR is 3.5 (Low). Significant vendor-NVD disagreement. |
| Affected Versions | Tomcat 9.0.0.M1–9.0.45, 10.0.0.M1–10.0.5, 8.5.0–8.5.65 |
| Fixed Versions | 9.0.46 (2021-05-12), 10.0.6, 8.5.66. Debian/Ubuntu/RHEL backports available since mid-2021. |
| Exposure Data | Shodan reports ~100k internet-facing Tomcat instances globally, but JNDIRealm usage is a small fraction. No scanner can remotely distinguish Realm type. |
| Disclosure & Credit | Disclosed 2021-07-12 via Apache Tomcat security mailing list. Reported to Apache by an unnamed researcher. |
noisgate verdict.
The single most decisive factor driving this downgrade is the non-default prerequisite: JNDIRealm is an opt-in Tomcat configuration used by a small minority of deployments, meaning the vulnerability is inapplicable to the vast majority of the installed base. Compounding this, the flaw only weakens lockout enforcement rather than bypassing authentication outright, produces no code execution, and has attracted zero public exploit tooling or observed campaigns in five years.
Why this verdict
- Non-default configuration gate: JNDIRealm must be explicitly configured in
server.xml. The default Tomcat install ships withUserDatabaseRealm. This alone makes the reachable population a small single-digit percentage of Tomcat deployments. - Lockout bypass ≠ auth bypass: The flaw lets an attacker circumvent LockOut Realm failure counters. It does not bypass authentication. The attacker still needs a correct or guessable password, and LockOut Realm itself is also a non-default opt-in feature.
- Zero weaponization signal: No public PoC, no Metasploit module, no Nuclei template, no KEV listing, no observed campaigns after 5+ years. Apache rates it Low. Tenable VPR is 3.5.
- Role multiplier: Tomcat *can* occupy high-value roles (Jenkins frontend, application tier for regulated data). However, CVE-2021-30640's chain requires JNDIRealm AND LockOut Realm AND a guessable password AND the absence of WAF/IdP/MFA — this compound prerequisite chain does not reliably succeed even in high-value roles. Jenkins, Nexus, and similar tools use their own auth subsystems independent of Tomcat Realms. The blast radius is limited to brute-force amplification against a single application's login, not domain/fleet/supply-chain compromise.
- CVSS AC:H acknowledged: Even NVD's own vector concedes High attack complexity, which is unusual for a MEDIUM rating and signals the scoring is at the ceiling of what the mechanics support.
Why not higher?
Upgrading to MEDIUM or above would require either a public PoC demonstrating reliable exploitation, evidence of in-the-wild campaigns, or a blast radius beyond single-application brute-force amplification. None of these conditions exist. The vulnerability requires a compound chain of non-default configurations (JNDIRealm + LockOut Realm) and still doesn't bypass authentication — it merely weakens rate limiting. Apache's own Low rating and Tenable's VPR 3.5 both confirm this isn't a MEDIUM-class risk.
Why not lower?
An IGNORE verdict would require the vulnerability to be entirely theoretical or affect only end-of-life software nobody runs. While the affected configuration is niche, JNDIRealm *is* documented, supported, and used in some enterprise LDAP-integrated Tomcat deployments. The CVSS Integrity-High component reflects that a successful lockout bypass meaningfully weakens a security control. Patching remains good hygiene for the minority of deployments that use JNDIRealm.
What to do — in priority order.
- Confirm whether JNDIRealm is in use — Grep
server.xmland allcontext.xmlfiles forJNDIRealm. If absent, this CVE is inapplicable to your host — tag it as a false positive in your scanner and move on. This takes minutes and eliminates noise from 90%+ of findings. - Front-end Tomcat auth with an IdP or SSO gateway — Move authentication to an identity provider (Okta, Azure AD, Keycloak) with MFA. This makes Tomcat Realm-level lockout bypass irrelevant because credentials never reach the Realm. No mitigation SLA applies at LOW severity — treat as backlog hygiene.
- Enable WAF brute-force rules on login endpoints — Configure your WAF or reverse proxy (mod_security, Cloudflare, AWS WAF) to rate-limit POST requests to authentication endpoints. This independently blocks the brute-force amplification the vulnerability enables.
- Patch to 9.0.46+ during next maintenance window — The fix has been available since May 2021 and is a minor version bump with no breaking changes. Roll it into your next scheduled Tomcat update cycle.
- Network segmentation alone — if the attacker is already on the internal network and the Tomcat login is reachable, segmentation doesn't prevent the lockout bypass. The control that matters is removing JNDIRealm or adding MFA.
- Tomcat LockOut Realm tuning (shorter lockout windows, lower thresholds) — the vulnerability bypasses the counter mechanism itself via username variants, so tightening parameters doesn't close the gap.
Crowdsourced verification payload.
Run this on each Tomcat host (Linux/macOS) as a user with read access to the Tomcat installation directory. Example: bash check_cve_2021_30640.sh /opt/tomcat. No root required.
#!/usr/bin/env bash
# check_cve_2021_30640.sh — Check for CVE-2021-30640 applicability and patch status
# Usage: bash check_cve_2021_30640.sh <CATALINA_HOME>
# Exit codes: 0=PATCHED/NOT_APPLICABLE, 1=VULNERABLE, 2=UNKNOWN
set -euo pipefail
CATALINA_HOME="${1:-}"
if [[ -z "$CATALINA_HOME" ]]; then
echo "Usage: $0 <CATALINA_HOME>"
exit 2
fi
# Step 1: Get Tomcat version
VERSION_SH="$CATALINA_HOME/bin/version.sh"
if [[ ! -x "$VERSION_SH" ]]; then
# Try catalina.sh version
VERSION_SH="$CATALINA_HOME/bin/catalina.sh"
fi
TOMCAT_VER=""
if [[ -f "$CATALINA_HOME/lib/catalina.jar" ]]; then
TOMCAT_VER=$(unzip -p "$CATALINA_HOME/lib/catalina.jar" org/apache/catalina/util/ServerInfo.properties 2>/dev/null | grep 'server.number=' | cut -d= -f2 | tr -d '[:space:]')
fi
if [[ -z "$TOMCAT_VER" ]]; then
echo "UNKNOWN — Could not determine Tomcat version at $CATALINA_HOME"
exit 2
fi
echo "Detected Tomcat version: $TOMCAT_VER"
# Step 2: Check if JNDIRealm is configured
JNDI_FOUND=false
while IFS= read -r -d '' f; do
if grep -qi 'JNDIRealm' "$f" 2>/dev/null; then
JNDI_FOUND=true
echo "WARNING: JNDIRealm found in $f"
fi
done < <(find "$CATALINA_HOME/conf" -name '*.xml' -print0 2>/dev/null)
# Step 3: Version comparison (9.x branch)
MAJOR=$(echo "$TOMCAT_VER" | cut -d. -f1)
MINOR=$(echo "$TOMCAT_VER" | cut -d. -f2)
PATCH=$(echo "$TOMCAT_VER" | cut -d. -f3)
VULNERABLE=false
if [[ "$MAJOR" -eq 9 ]] && [[ "$MINOR" -eq 0 ]] && [[ "$PATCH" -lt 46 ]]; then
VULNERABLE=true
elif [[ "$MAJOR" -eq 10 ]] && [[ "$MINOR" -eq 0 ]] && [[ "$PATCH" -lt 6 ]]; then
VULNERABLE=true
elif [[ "$MAJOR" -eq 8 ]] && [[ "$MINOR" -eq 5 ]] && [[ "$PATCH" -lt 66 ]]; then
VULNERABLE=true
fi
# Step 4: Report
if [[ "$VULNERABLE" == true ]]; then
if [[ "$JNDI_FOUND" == true ]]; then
echo "VULNERABLE — Tomcat $TOMCAT_VER with JNDIRealm configured. CVE-2021-30640 is applicable."
exit 1
else
echo "PATCHED (effectively) — Tomcat $TOMCAT_VER is in the affected range but JNDIRealm is NOT configured. CVE-2021-30640 is not applicable to this host."
exit 0
fi
else
echo "PATCHED — Tomcat $TOMCAT_VER is not in the affected version range."
exit 0
fiIf you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.