← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2025-67733 · CWE-74 · Disclosed 2026-02-23

Valkey is a distributed key-value database

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

This is less a front-door break-in and more a poisoned note slipped into a shared mail slot

CVE-2025-67733 is a RESP response-stream injection flaw in Valkey's Lua error path. In affected releases—up to 7.2.11, 8.0.6, 8.1.5, and 9.0.1—an attacker who can execute scripting commands can craft an error containing control bytes so leftover data is interpreted as a later reply on the same connection. Upstream fixed it in 7.2.12, 8.0.7, 8.1.6, and 9.0.2 on February 23, 2026.

GitHub's CNA score of 8.5 is technically defensible in a lab, but it overstates most enterprise reality. The decisive friction is that exploitation usually requires more than raw network reachability: the attacker needs authenticated or application-mediated access to EVAL/FCALL, and the environment has to reuse a Valkey connection across trust boundaries so another operation consumes the poisoned reply. That is materially narrower than a normal unauthenticated remote service exploit, so this gets downgraded to MEDIUM.

"This is a real bug with a public PoC, but it is mostly a shared-connection, authenticated-path problem—not an internet-worm problem."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Reach a Valkey path that accepts scripting

The attacker needs a live route to Valkey itself or to an application backend that passes user-controlled input into Valkey scripting. In practice this is done with valkey-cli, a native client library, or an app feature that ultimately issues EVAL, EVALSHA, or FCALL.
Conditions required:
  • Network reachability to Valkey or to an application tier that can invoke Valkey scripting
  • Authentication or an exposed application path that effectively grants scripting capability
Where this breaks in practice:
  • Valkey's own security guidance expects trusted internal clients and recommends firewalling the service
  • Many enterprises do not expose port 6379 externally and do not grant scripting commands to low-trust users
Detection/coverage: Asset scanners and config audits catch exposed 6379; local checks are stronger than remote probes because the flaw itself is version- and privilege-dependent.
STEP 02

Send a malformed Lua error reply

Using a tool like the public JYlab/CVE-2025-67733 PoC, the attacker triggers a Lua script error that embeds RESP control characters into the error stream. The vulnerable parser/flush path mishandles null or delimiter bytes and leaves attacker-controlled bytes queued for later consumption.
Conditions required:
  • Ability to run EVAL/EVALSHA/FCALL or otherwise hit an app path that does so
  • Affected Valkey version
Where this breaks in practice:
  • ACLs can remove @scripting access entirely
  • Applications that never expose user-controlled Lua or stored functions break this chain
Detection/coverage: Look for EVAL/FCALL usage from low-trust users, abnormal Lua errors, and denied scripting attempts in ACL LOG; generic network IDS coverage is weak.
STEP 03

Poison a shared backend connection

The exploit matters only if the injected bytes remain on a connection that will later service another logical request. That is easiest where a web app, API tier, or custom pool multiplexes multiple user actions across a reused Valkey connection.
Conditions required:
  • Connection reuse or pooling across requests, tenants, or security contexts
  • A client library or app behavior that does not fully drain and discard the poisoned connection
Where this breaks in practice:
  • Many modern pools dedicate a connection per worker or drop connections on protocol errors
  • Single-purpose internal services often do not mix attacker and victim traffic on one socket
Detection/coverage: App-side protocol desync, unexplained cache value anomalies, and client reconnect spikes are better clues than signature-based scanners.
STEP 04

Victim operation consumes the forged reply

A later legitimate command reads the leftover RESP fragment and receives attacker-chosen data or protocol corruption. The impact is integrity tampering and possible application-layer denial of service, not host takeover or code execution.
Conditions required:
  • A subsequent command on the same socket
  • Application logic that trusts the returned value
Where this breaks in practice:
  • Timing has to line up with connection reuse
  • Blast radius is typically limited to consumers of that shared connection rather than the whole server or fleet
Detection/coverage: Expect inconsistent app behavior, cache corruption complaints, or parser errors; version-only scanners can identify exposure, but not successful exploitation.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo authoritative exploitation evidence found. It is not listed in CISA's KEV catalog, and I found no primary-source reporting of active campaigns.
Proof-of-concept availabilityPublic PoC exists. Researcher JYlab published github.com/JYlab/CVE-2025-67733, including attacker_client.py, backend.py, and a shared-connection demo.
EPSS0.00023 (~0.023%) from your intel block, which is very low and lines up with a niche exploitation path rather than broad criminal demand.
KEV statusNot KEV-listed as of this assessment; disclosure was 2026-02-23.
CVSS disagreementGitHub CNA: 8.5 with S:C; NVD: 7.1 with S:U. That mismatch is a clue the cross-component blast radius is debatable in real deployments.
Affected versionsUpstream impact covers <=7.2.11, 8.0.0-8.0.6, 8.1.0-8.1.5, and 9.0.0-9.0.1.
Fixed versionsUpstream fixes landed in 7.2.12, 8.0.7, 8.1.6, and 9.0.2. Distro backports include Debian 8.1.1+dfsg1-3+deb13u2, Ubuntu fixes via USN-8106-1, and SUSE advisories marking package updates available.
Exposure / scanning realityReachable population is the real governor here. Valkey docs explicitly say the service should be accessible only to trusted clients and firewalled; Censys has historically observed large public Redis/RESP exposure on port 6379, but that is an exposure problem, not proof this specific bug is broadly reachable.
Scanner coverageTenable added coverage quickly: 299872 for unpatched Linux distros and 305038 for Debian DSA-6198. Detection is largely version/package-based, not exploit-behavior-based.
Researcher / sourceThe advisory credits JYlab as the finder; GitHub published the advisory on 2026-02-23.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (6.1/10)

The single biggest downgrade factor is attacker position: this is usually an authenticated or application-mediated scripting path, not a no-auth internet exploit. The second is blast-radius friction: exploitation depends on shared-connection reuse, so many otherwise-affected deployments never present a clean victim path.

HIGH Affected-version and fixed-version mapping
MEDIUM Real-world exploitability across enterprise deployments

Why this verdict

  • Start at the vendor's 8.5 because a network-reachable, low-complexity bug in a common data tier deserves attention on paper
  • Down for attacker position: exploitation generally requires authenticated Valkey access or an application path that exposes EVAL/FCALL, which implies prior trust or a design flaw upstream of Valkey
  • Down for population reachability: many enterprises keep Valkey internal, firewalled, and behind app mediation, so the exposed population is much smaller than the CVSS baseline assumes
  • Down for chain fragility: the exploit needs connection reuse across security contexts so a victim consumes the poisoned reply; that dependency knocks out many well-behaved deployments
  • Back up slightly because PoC is public: once the prerequisites are present, weaponization is practical and integrity impact is real

Why not higher?

There is no host compromise here: no RCE, no auth bypass, no privilege escalation, and no broad server-side data theft primitive by itself. The exploit chain is materially narrower than the vendor score suggests because it depends on both scripting access and a vulnerable connection-sharing pattern.

Why not lower?

This is still not harmless. If your application lets low-trust users touch Valkey scripting and reuses a backend connection, a real attacker can tamper with other users' replies or trigger application instability with off-the-shelf PoC code.

05 · Compensating Control

What to do — in priority order.

  1. Remove scripting from low-trust ACLs — Deny @scripting or explicitly block EVAL, EVALSHA, FCALL, and FUNCTION LOAD for any account used by applications or users that do not need programmability. For a MEDIUM verdict there is no noisgate mitigation SLA; deploy this now where feasible, otherwise go straight to the remediation window.
  2. Fence Valkey behind internal-only network policy — Restrict port 6379 to trusted app tiers and admin networks only, and verify there is no direct internet path. Again, there is no noisgate mitigation SLA for MEDIUM, but external exposure is the one condition most likely to turn this from niche to operationally painful.
  3. Separate trust domains at the connection layer — Do not let attacker-controlled and victim traffic share the same backend Valkey connection or pool when scripting is in play. Use per-service or per-tenant pools and drop sockets on protocol or Lua error anomalies; do this during the normal remediation window if you cannot harden it immediately.
  4. Audit for unexpected scripting use — Inventory where your estate actually uses Lua scripts or Valkey functions, because environments that never use them can usually shut the feature off for app identities with minimal breakage. That sharply reduces reachable exploit surface without waiting for a code release.
What doesn't work
  • TLS only does not help; it protects the channel, not the response-parsing flaw or shared-connection poisoning path
  • A generic WAF usually does not help because the vulnerable traffic is native RESP to Valkey or app-internal use of scripting commands, not HTTP payload inspection
  • Hiding the version banner does not matter; once an attacker can execute scripting commands, exploit success depends on behavior and version, not banner secrecy
06 · Verification

Crowdsourced verification payload.

Run this on the target Valkey host or from an auditor box that has valkey-cli access to the instance. Invoke it as ./check_cve_2025_67733.sh 127.0.0.1 6379 or ./check_cve_2025_67733.sh valkey01.example.com 6379 'password'; no root is required unless you rely on local package-manager fallback.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# noisgate verifier for CVE-2025-67733
# Usage: ./check_cve_2025_67733.sh [host] [port] [password]
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -euo pipefail

HOST="${1:-127.0.0.1}"
PORT="${2:-6379}"
PASS="${3:-}"
VERSION=""

ver_ge() {
  # returns success if $1 >= $2
  [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$2" ]
}

trim_version() {
  echo "$1" | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+' | head -n1 || true
}

get_from_cli() {
  if ! command -v valkey-cli >/dev/null 2>&1; then
    return 1
  fi

  local auth_args=()
  if [ -n "$PASS" ]; then
    auth_args=(-a "$PASS")
  fi

  local info out
  if out=$(valkey-cli -h "$HOST" -p "$PORT" "${auth_args[@]}" --raw INFO server 2>/dev/null); then
    info="$out"
    VERSION=$(echo "$info" | awk -F: '/^valkey_version:/{print $2}' | tr -d '\r' | head -n1)
    if [ -z "$VERSION" ]; then
      VERSION=$(echo "$info" | awk -F: '/^redis_version:/{print $2}' | tr -d '\r' | head -n1)
    fi
    VERSION=$(trim_version "$VERSION")
    [ -n "$VERSION" ]
    return 0
  fi

  return 1
}

get_from_server_binary() {
  if ! command -v valkey-server >/dev/null 2>&1; then
    return 1
  fi

  local out
  out=$(valkey-server --version 2>/dev/null || true)
  VERSION=$(trim_version "$out")
  [ -n "$VERSION" ]
}

get_from_packages() {
  if command -v dpkg-query >/dev/null 2>&1; then
    VERSION=$(dpkg-query -W -f='${Version}\n' valkey-server 2>/dev/null | head -n1 || true)
    VERSION=$(trim_version "$VERSION")
    [ -n "$VERSION" ] && return 0

    VERSION=$(dpkg-query -W -f='${Version}\n' valkey 2>/dev/null | head -n1 || true)
    VERSION=$(trim_version "$VERSION")
    [ -n "$VERSION" ] && return 0
  fi

  if command -v rpm >/dev/null 2>&1; then
    VERSION=$(rpm -q --qf '%{VERSION}\n' valkey 2>/dev/null | head -n1 || true)
    VERSION=$(trim_version "$VERSION")
    [ -n "$VERSION" ] && return 0
  fi

  return 1
}

is_vulnerable() {
  local v="$1"

  # Affected upstream ranges:
  #   < 7.2.12
  #   8.0.0 - 8.0.6
  #   8.1.0 - 8.1.5
  #   9.0.0 - 9.0.1

  if ver_ge "$v" "9.0.0" && ! ver_ge "$v" "9.0.2"; then
    return 0
  fi

  if ver_ge "$v" "8.1.0" && ! ver_ge "$v" "8.1.6"; then
    return 0
  fi

  if ver_ge "$v" "8.0.0" && ! ver_ge "$v" "8.0.7"; then
    return 0
  fi

  if ! ver_ge "$v" "7.2.12"; then
    return 0
  fi

  return 1
}

main() {
  get_from_cli || get_from_server_binary || get_from_packages || true

  if [ -z "$VERSION" ]; then
    echo "UNKNOWN - unable to determine Valkey version"
    exit 2
  fi

  if is_vulnerable "$VERSION"; then
    echo "VULNERABLE - detected version $VERSION"
    exit 1
  else
    echo "PATCHED - detected version $VERSION"
    exit 0
  fi
}

main "$@"
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, do two things: first, identify every Valkey deployment where untrusted users can reach scripting commands or where app pools may share a backend connection across trust boundaries; second, patch the affected branches to 7.2.12 / 8.0.7 / 8.1.6 / 9.0.2+. For a MEDIUM verdict there is no noisgate mitigation SLA — go straight to the 365-day remediation window; complete the actual version remediation within the noisgate remediation SLA of ≤365 days, but pull that forward on any internet-facing or multi-tenant deployment because those are the few places this bug stops being theoretical.

Sources

  1. NVD CVE record
  2. GitHub Security Advisory
  3. Public PoC by JYlab
  4. Valkey security guidance
  5. CISA KEV catalog
  6. Ubuntu USN-8106-1
  7. Debian DSA-6198-1
  8. SUSE CVE page
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.