This is a bad gearbox in the shop forklift, not a hole in the perimeter fence
CVE-2025-5222 is a stack overflow in ICU's genrb tool, specifically SRBRoot::addTag in parse.cpp, triggered while converting crafted resource-bundle input. The bug was reproduced on ICU 76.0.1; NVD later mapped affected upstream trains as releases before 77.1 and before 78.1 depending on branch, and multiple distros backported the fix into older package lines rather than bumping to those upstream versions.
The vendor's 7.0 HIGH is technically defensible if you score the memory-corruption outcome in a vacuum, but it overstates day-two enterprise risk. The attack is *local*, *high complexity*, and *user-interaction dependent*, and it hits a command-line build/localization tool rather than a long-running network-facing service; in most estates that means exposure is concentrated in developer workstations, build runners, and software packaging pipelines.
4 steps from start to impact.
Land crafted localization input
genrb. In practice that usually means a poisoned third-party localization file, dependency source tree, or build artifact rather than direct exploitation of a production daemon.- Attacker can supply or influence ICU resource-bundle input
- Target organization uses ICU
genrbin packaging, build, or localization workflows
- Most enterprises never run
genrbon endpoints outside dev/build roles - Input usually comes from trusted internal repos, not arbitrary internet users
genrb is actually used in that environment.Trigger the vulnerable parser via genrb
genrb on the crafted file. The overflow sits in SRBRoot::addTag; upstream fixed it by replacing a fixed-size char subtag[1024] buffer with CharString handling in commit 2c667e3.- A human or automated build process runs
genrb - The installed ICU build predates the fix or lacks a distro backport
- This is not a drive-by bug; something must deliberately execute the tool
- Modern build pipelines often isolate untrusted jobs or reject unexpected resource files
Convert overflow into code execution
- Target binary is exploitable despite compiler and platform hardening
- Attacker can shape memory state well enough for post-overflow control
- CVSS already marks this
AC:H, and distro hardening raises the bar further - A failed exploit often just kills the tool instead of yielding code execution
Operate within the local blast radius
- Invoking account has meaningful local or pipeline privileges
- Attacker can leverage local execution for credential theft, artifact tampering, or lateral movement
- Blast radius is usually one workstation, one build container, or one runner
- MFA, repo protections, EDR, and runner isolation limit post-exploitation payoff
The supporting signals.
| In-the-wild status | No authoritative evidence of active exploitation found in CISA KEV or vendor advisories during this review. |
|---|---|
| KEV status | Not KEV-listed as of this assessment; CISA's catalog is the authoritative check. |
| Proof-of-concept availability | There is at least a public reproduction/backport path: upstream fix commit 2c667e3 and a public Debian packaging repo from berkley4 carrying the fix for ICU 74.2. |
| EPSS | 0.00033 from the supplied intel; secondary feeds report roughly the 14th percentile, which is consistent with a low-likelihood local-tool issue. |
| CVSS vector meaning | AV:L/AC:H/PR:N/UI:R is the whole story: local only, hard to exploit, needs someone or something to run the tool. |
| Affected versions | Confirmed on ICU 76.0.1; NVD change history later associated vulnerable upstream ranges with releases before 77.1 and before 78.1 by branch. |
| Fixed versions | Upstream fix landed in commit 2c667e3; practical fixes include upstream 77.1/78.1 and distro backports such as Debian 67.1-7+deb11u1, Debian 72.1-3+deb12u1, and RHEL/OL9 67.1-10.el9_6. |
| Exposure/scanning reality | This is not internet-scannable in the usual Shodan/Censys sense because the vulnerable surface is the local genrb executable, not a listening service. |
| Disclosure date | Publicly disclosed on 2025-05-27; upstream fix commit predates that, dated 2025-01-22. |
| Reporting / provenance | CVE was published by Red Hat; the code fix was committed upstream by Frank Tang in the unicode-org/icu repository. |
noisgate verdict.
The single biggest severity reducer is that this bug lives in genrb, a local command-line build tool, not a remotely reachable service. That sharply limits reachable population and turns exploitation into a supply-chain or workstation problem, not a broad enterprise intrusion path.
Why this verdict
- Down from vendor HIGH because attacker position is local: the chain starts at
AV:L, which implies the adversary already has code delivery into a workstation, build host, or CI context. - Further down because it needs execution of a specific tool: the vulnerable component is
genrb, so only systems that actually compile ICU resource bundles are in scope; that is a small subset of a 10,000-host estate. - Further down because real deployments add friction:
AC:H+UI:R+ compiler hardening mean many environments are more likely to see a crash than clean weaponization, and EDR/runner isolation should constrain the payoff.
Why not higher?
This is not unauthenticated remote, not broadly exposed, and not a common server-side runtime path. Most enterprises can remove 95%+ of the estate from concern immediately because ordinary user endpoints and production servers never invoke genrb.
Why not lower?
It is still a memory-corruption bug with plausible local code execution under the invoking account. On developer laptops, packaging hosts, and CI runners that ingest third-party source or localization files, that can become a meaningful foothold or artifact-tampering opportunity.
What to do — in priority order.
- Constrain
genrbto trusted build contexts — Run ICU resource compilation only on managed developer workstations and isolated CI runners, not on general-purpose servers. For a LOW verdict there is no formal mitigation deadline, but do this as backlog hygiene in the same maintenance cycle where you review build-tool exposure. - Isolate untrusted builds — If you build third-party or community code, keep those jobs in disposable containers/VMs with no long-lived secrets and no signing keys. That shrinks the local blast radius even if
genrbis triggered before the patch lands. - Protect artifact-signing and CI credentials — Keep signing keys, package publishing tokens, and repo credentials out of the same execution context as untrusted build jobs. This matters more than the overflow itself because the realistic damage path is CI or developer-account abuse.
- Inventory actual
genrbusage — Prioritize hosts withicu-devtools, package-build roles, or source trees invokinggenrb; most other systems can be deprioritized. For LOW, do this during routine vulnerability triage rather than emergency response.
- A perimeter firewall does not help because there is no network listener to shield.
- WAF rules do not help because exploitation is not delivered over HTTP to a service endpoint.
- Blindly chasing every host with
libicuinstalled overstates risk; the meaningful exposure is wheregenrbis present and actually used.
Crowdsourced verification payload.
Run this on the target Linux host or build runner that has ICU installed. Invoke it as sudo bash check-cve-2025-5222.sh for package-based checks, or bash check-cve-2025-5222.sh /path/to/icu-source to inspect a source tree directly; root is recommended so RPM changelog queries work reliably.
#!/usr/bin/env bash
# check-cve-2025-5222.sh
# Detect likely exposure to CVE-2025-5222 on Linux hosts.
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
SOURCE_ROOT="${1:-}"
patched() {
echo "PATCHED"
exit 0
}
vulnerable() {
echo "VULNERABLE"
exit 1
}
unknown() {
echo "UNKNOWN"
exit 2
}
# 1) Source-tree check: look for upstream fix pattern in parse.cpp
if [ -n "$SOURCE_ROOT" ]; then
PARSE_CPP=""
if [ -f "$SOURCE_ROOT/icu4c/source/tools/genrb/parse.cpp" ]; then
PARSE_CPP="$SOURCE_ROOT/icu4c/source/tools/genrb/parse.cpp"
elif [ -f "$SOURCE_ROOT/source/tools/genrb/parse.cpp" ]; then
PARSE_CPP="$SOURCE_ROOT/source/tools/genrb/parse.cpp"
fi
if [ -n "$PARSE_CPP" ]; then
if grep -q 'CharString[[:space:]]\+subtag;' "$PARSE_CPP"; then
patched
fi
if grep -q 'char[[:space:]]\+subtag\[1024\];' "$PARSE_CPP"; then
vulnerable
fi
unknown
fi
fi
# 2) Debian/Ubuntu package checks
if command -v dpkg-query >/dev/null 2>&1; then
if dpkg-query -W -f='${Status}' icu-devtools 2>/dev/null | grep -q 'install ok installed'; then
ver="$(dpkg-query -W -f='${Version}' icu-devtools 2>/dev/null)"
# Debian 11 backport
if dpkg --compare-versions "$ver" ge '67.1-7+deb11u1'; then
patched
fi
# Debian 12 / Ubuntu-derived 72.x line backport
if dpkg --compare-versions "$ver" ge '72.1-3+deb12u1'; then
patched
fi
# Upstream fixed lines commonly seen in custom packages
if dpkg --compare-versions "$ver" ge '77.1'; then
patched
fi
vulnerable
fi
# Fallback if icu-devtools is absent but libicu is present
for pkg in libicu72 libicu74 libicu76 libicu77 libicu78 libicu67; do
if dpkg-query -W -f='${Status}' "$pkg" 2>/dev/null | grep -q 'install ok installed'; then
ver="$(dpkg-query -W -f='${Version}' "$pkg" 2>/dev/null)"
if dpkg --compare-versions "$ver" ge '72.1-3+deb12u1'; then
patched
fi
if dpkg --compare-versions "$ver" ge '77.1'; then
patched
fi
vulnerable
fi
done
fi
# 3) RPM-based checks: changelog marker is safer than upstream version guessing because of backports
if command -v rpm >/dev/null 2>&1; then
if rpm -q icu >/dev/null 2>&1; then
if rpm -q --changelog icu 2>/dev/null | grep -q 'ICU-22973'; then
patched
fi
if rpm -q --changelog icu 2>/dev/null | grep -q 'CVE-2025-5222'; then
patched
fi
vulnerable
fi
for pkg in libicu libicu-devel icu; do
if rpm -q "$pkg" >/dev/null 2>&1; then
if rpm -q --changelog "$pkg" 2>/dev/null | grep -q 'ICU-22973'; then
patched
fi
if rpm -q --changelog "$pkg" 2>/dev/null | grep -q 'CVE-2025-5222'; then
patched
fi
vulnerable
fi
done
fi
# 4) Binary-only fallback
if command -v genrb >/dev/null 2>&1; then
# Binary present but package/source evidence unavailable
unknown
fi
unknownIf you remember one thing.
genrb—developer workstations, package builders, and CI runners—and document everything else as out-of-scope. For a LOW verdict there is no noisgate mitigation SLA and no noisgate remediation SLA; treat it as backlog hygiene, fold the patch into routine ICU/toolchain updates, and prioritize only those build environments that process third-party or untrusted localization content.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.