← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-50593 · CWE-191 · Disclosed 2026-06-05

Graphite before 1

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a sharp shard hidden inside a rare font file, not a worm in your front door

CVE-2026-50593 is an integer underflow in Graphite2's handling of Graphite actions that can turn into an out-of-bounds write when slotat is fed hostile data. The affected range is Graphite/Graphite2 before 1.3.15, with the fix landing in upstream release 1.3.15 published on 2026-05-31; the CVE was disclosed on 2026-06-05. In practice, the bug matters when an application using Graphite2 renders a specially crafted Graphite-enabled font or document content that triggers that code path.

The vendor's HIGH 7.3 score is technically defensible for memory corruption, but it overstates enterprise urgency. This is not a remotely reachable server bug; the attacker needs local-style delivery plus user interaction, and the vulnerable code sits in a comparatively niche smart-font rendering path rather than a broadly exposed network daemon. For a fleet manager, that makes this a client-side hardening issue, not an immediate patch-everything incident.

"Real memory corruption, but it sits behind local file delivery, user interaction, and a niche font engine path."
02 · The Attack Path

3 steps from start to impact.

STEP 01

Deliver a malicious Graphite-enabled font or document

The attacker needs content that causes a target application to load a crafted Graphite font and evaluate Graphite actions. A realistic weaponization path is a booby-trapped document, package, or bundled font set created with custom tooling rather than an off-the-shelf exploit kit. No public turnkey exploit repo was located during this assessment.
Conditions required:
  • Target uses an application linked against vulnerable Graphite2 before 1.3.15
  • Attacker can get the target to open or render attacker-controlled content
  • The content includes a Graphite-enabled font path that reaches Graphite actions
Where this breaks in practice:
  • Graphite is a niche shaping engine compared with mainstream OpenType-only flows
  • Many enterprise users never encounter Graphite-enabled fonts at all
  • Email security, browser sandboxing, file reputation, and attachment filtering may block first-stage delivery
Detection/coverage: Traditional network scanners will miss this entirely; coverage is mostly SBOM/package inventory plus application crash telemetry.
STEP 02

Trigger the slotat underflow during shaping

When the application renders the malicious font data, Graphite action processing can hit the integer underflow condition and compute a bad index. That malformed index can then produce an out-of-bounds write in the client process. This is a memory-corruption primitive, but exploit reliability depends on the surrounding application, allocator behavior, and sandboxing.
Conditions required:
  • User opens the file, preview, page, or content that invokes shaping
  • The application actually enables the Graphite code path for that font
  • The host is running a vulnerable build without downstream backport fix
Where this breaks in practice:
  • User interaction is mandatory per the supplied CVSS vector
  • Many renderers will crash before a clean code-exec primitive is achieved
  • Modern ASLR, DEP, CFI, and app sandboxing raise exploit-development cost
Detection/coverage: EDR may see the resulting application crash or exploit-guard event, but signature-based detection of the malformed font logic is weak.
STEP 03

Convert corruption into impact inside the client app

Successful exploitation would most likely yield denial of service first, and potentially arbitrary code execution in the context of the rendering process if the attacker can stabilize the memory corruption. Impact is bounded by the privileges and sandbox of the hosting application, which is why Firefox-style or document-viewer sandboxes matter here. There is no public evidence yet that attackers have done this in the wild.
Conditions required:
  • The memory corruption is controllable enough for the target app and platform
  • The hosting process has meaningful post-exploitation value
  • Additional sandbox escape is not required or is separately achieved
Where this breaks in practice:
  • Client-process compromise is less useful than server-side unauthenticated RCE
  • Sandboxed renderers can sharply reduce blast radius
  • Exploit chains against desktop apps usually need more than one bug
Detection/coverage: Post-exploitation visibility depends on the parent process; EDR is more likely to catch follow-on payload behavior than the initial font parser fault.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo public exploitation evidence found during this review, and the CVE is not in CISA KEV.
KEV statusNot listed in the CISA Known Exploited Vulnerabilities catalog as of this assessment.
Proof-of-concept availabilityNo public PoC or exploit repository for CVE-2026-50593 was located in upstream GitHub release metadata or general web search. Expect custom one-off exploit development if this gets weaponized.
EPSSNo CVE-specific public EPSS value was located at assessment time. FIRST documents the EPSS feed and API, but this CVE's score was not retrievable from the sources available here.
CVSS vector meaningCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:H/A:H means local-style delivery + user interaction with no prior auth, and heavy integrity/availability impact if exploitation succeeds.
Affected versionsUpstream Graphite/Graphite2 before 1.3.15.
Fixed versionUpstream fixed in 1.3.15; downstream distro packages may carry backports without reporting upstream version parity, so package-version-only checks can under-report patch status.
Exposure realityThis is a library bug, not a listening service. Shodan/Censys/FOFA-style Internet exposure counts are not meaningful; reachability depends on applications that parse attacker-controlled Graphite fonts.
Where Graphite shows upGraphite's own technical overview says Graphite2 is used by LibreOffice and Firefox, which makes this primarily a desktop/client rendering concern rather than a server patching emergency.
Disclosure timelineUpstream 1.3.15 release published 2026-05-31; the CVE was disclosed 2026-06-05.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (5.2/10)

The decisive factor is attacker position: this bug needs user-driven rendering of attacker-controlled content in a client application, not unauthenticated remote reachability to a service. That sharply shrinks exposed population and makes the vendor's memory-corruption baseline too hot for enterprise patch-priority purposes.

HIGH Attack preconditions are materially narrower than a server-side remote exploit
MEDIUM Affected population in enterprise endpoints using Graphite-enabled rendering paths
MEDIUM Potential for code execution versus crash-only outcomes

Why this verdict

  • Requires user interaction: the supplied vector includes UI:R, which means no hands-free exploitation against your fleet.
  • Post-delivery bug, not initial-access magic: the attacker still has to land a malicious document/font/web payload on the endpoint first, so email security, browser controls, and user workflows apply downward pressure.
  • Niche reachable surface: Graphite is a specialized smart-font engine, not a universally exposed parser path across every desktop workload.
  • No KEV / no public campaign evidence: absent exploitation evidence, there is no reason to override the strong precondition friction.
  • Blast radius is process-bounded: even if corruption becomes code execution, impact is initially constrained to the hosting client application's privilege and sandbox.

Why not higher?

It is not higher because the attacker does not get unauthenticated remote reachability into a service you expose to the network. This is a client-side parser bug behind user interaction and a relatively uncommon Graphite rendering path, which is a major real-world downgrade from the vendor headline score.

Why not lower?

It is not lower because this is still genuine memory corruption with an out-of-bounds write, not a benign crash or purely theoretical correctness bug. If your estate includes LibreOffice, Firefox, or other Graphite-linked apps handling untrusted content, the bug can still matter on high-risk endpoints.

05 · Compensating Control

What to do — in priority order.

  1. Prioritize risky renderers — Identify endpoints running Graphite-linked applications that open untrusted documents or web content, especially shared workstations and internet-facing user populations. Because this verdict is MEDIUM, there is no mitigation SLA — go straight to the 365-day remediation window, but do the inventory work now so the patch does not disappear into desktop drift.
  2. Reduce untrusted font paths — Harden workflows that allow arbitrary bundled fonts in documents, archives, and downloaded content. This lowers exposure while you patch, and for a MEDIUM item it should be folded into normal hardening rather than emergency change activity.
  3. Watch for renderer crashes — Tune EDR, crash reporting, and application telemetry for repeated faults in browsers, office suites, or document viewers linked against Graphite2. This is not a reliable prevention control, but it is a practical tripwire while remediation proceeds within the 365-day window.
  4. Use distro backport evidence — For Linux estates, verify whether your distro has backported the fix even if the package version still reads 1.3.14 or similar. Do this during normal remediation planning so you do not create false positives and unnecessary churn.
What doesn't work
  • Perimeter network scanning doesn't help; this is not a remotely enumerable service.
  • WAF rules don't help; the vulnerable surface is local/client-side font shaping, not HTTP request parsing.
  • MFA is irrelevant; there is no authentication boundary in the exploit chain.
06 · Verification

Crowdsourced verification payload.

Run this on the target Linux/macOS host or in your gold-image/CI environment. Invoke it as bash check-graphite2-cve-2026-50593.sh with standard user rights; root is only needed if you want package-manager visibility the current user lacks. The script checks pkg-config, common package managers, and library locations, then reports VULNERABLE, PATCHED, or UNKNOWN.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check-graphite2-cve-2026-50593.sh
# Determine likely exposure to CVE-2026-50593 in Graphite2.
# Exit codes: 0 PATCHED, 1 VULNERABLE, 2 UNKNOWN

set -u

TARGET_FIXED="1.3.15"
FOUND_VERSION=""
SOURCE=""

ver_lt() {
  # returns 0 if $1 < $2
  [ "$(printf '%s
%s
' "$1" "$2" | sort -V | head -n1)" != "$2" ]
}

pick_version() {
  local v="$1"
  local s="$2"
  if [ -n "$v" ] && [ -z "$FOUND_VERSION" ]; then
    FOUND_VERSION="$v"
    SOURCE="$s"
  fi
}

# 1) pkg-config
if command -v pkg-config >/dev/null 2>&1; then
  V=$(pkg-config --modversion graphite2 2>/dev/null)
  pick_version "$V" "pkg-config"
fi

# 2) dpkg
if [ -z "$FOUND_VERSION" ] && command -v dpkg-query >/dev/null 2>&1; then
  V=$(dpkg-query -W -f='${Version}' graphite2 2>/dev/null | head -n1)
  pick_version "$V" "dpkg"
fi

# 3) rpm
if [ -z "$FOUND_VERSION" ] && command -v rpm >/dev/null 2>&1; then
  V=$(rpm -q --qf '%{VERSION}-%{RELEASE}' graphite2 2>/dev/null | head -n1)
  pick_version "$V" "rpm"
fi

# 4) pacman
if [ -z "$FOUND_VERSION" ] && command -v pacman >/dev/null 2>&1; then
  V=$(pacman -Q graphite2 2>/dev/null | awk '{print $2}' | head -n1)
  pick_version "$V" "pacman"
fi

# 5) Homebrew
if [ -z "$FOUND_VERSION" ] && command -v brew >/dev/null 2>&1; then
  V=$(brew list --versions graphite2 2>/dev/null | awk '{print $2}' | head -n1)
  pick_version "$V" "brew"
fi

# 6) Fallback library filenames / strings
if [ -z "$FOUND_VERSION" ]; then
  for f in /usr/lib*/libgraphite2.so* /usr/local/lib*/libgraphite2.so* /opt/homebrew/lib/libgraphite2.dylib /usr/local/lib/libgraphite2.dylib; do
    [ -e "$f" ] || continue
    V=$(strings "$f" 2>/dev/null | grep -Eo '1\.[0-9]+\.[0-9]+' | sort -V | tail -n1)
    if [ -n "$V" ]; then
      pick_version "$V" "library-strings:$f"
      break
    fi
  done
fi

if [ -z "$FOUND_VERSION" ]; then
  echo "UNKNOWN - graphite2 version not found via pkg-config/package manager/library scan"
  exit 2
fi

# Normalize obvious distro suffixes like 1.3.14-11
BASE_VERSION=$(printf '%s' "$FOUND_VERSION" | grep -Eo '^[0-9]+\.[0-9]+\.[0-9]+' )
if [ -z "$BASE_VERSION" ]; then
  echo "UNKNOWN - found version '$FOUND_VERSION' from $SOURCE but could not normalize"
  exit 2
fi

# Package backports complicate a pure version check.
if [ "$BASE_VERSION" = "1.3.14" ] && [ "$FOUND_VERSION" != "$BASE_VERSION" ]; then
  echo "UNKNOWN - found $FOUND_VERSION from $SOURCE; upstream base is vulnerable, but distro may have backported the fix"
  exit 2
fi

if ver_lt "$BASE_VERSION" "$TARGET_FIXED"; then
  echo "VULNERABLE - found Graphite2 $FOUND_VERSION via $SOURCE (upstream fixed in $TARGET_FIXED)"
  exit 1
fi

echo "PATCHED - found Graphite2 $FOUND_VERSION via $SOURCE"
exit 0
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: treat this as a desktop/library cleanup item, not a stop-the-line event. Use asset inventory and SBOM/package data to find Graphite2 consumers, focus first on endpoints that routinely render untrusted documents or web content, and validate distro backports before opening tickets. For a MEDIUM verdict there is no noisgate mitigation SLA — go straight to the 365-day remediation window; patch to 1.3.15 or an equivalent downstream backport within the noisgate remediation SLA of ≤365 days.

Sources

  1. Upstream Graphite repository
  2. Upstream Graphite releases
  3. Release metadata showing 1.3.15 published May 31, 2026
  4. Graphite technical overview and deployment context
  5. Debian source view for Graphite2 1.3.14 codebase
  6. MacPorts package metadata for graphite2
  7. CISA Known Exploited Vulnerabilities catalog
  8. FIRST EPSS data and statistics
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.