Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2025-69277

CVE-2025-69277: libsodium Elliptic Curve Validation Flaw

CVE-2025-69277 is an elliptic curve point validation flaw in libsodium that incorrectly accepts invalid points outside the main cryptographic group. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2025-69277 Overview

CVE-2025-69277 is a cryptographic validation flaw in libsodium versions prior to commit ad3004e. The crypto_core_ed25519_is_valid_point() function fails to correctly reject Ed25519 elliptic curve points that lie outside the main cryptographic subgroup. The check only verified that the X coordinate was zero after scalar multiplication by the group order, missing cases where the point was a small-order element not on the prime-order subgroup. This affects atypical use cases where libsodium consumers pass untrusted or attacker-controlled points into custom cryptographic protocols built on top of Ed25519 primitives.

Critical Impact

Applications relying on crypto_core_ed25519_is_valid_point() to filter untrusted curve points may accept small-order points, weakening custom protocols such as key exchange or blind signatures that depend on strict subgroup membership.

Affected Products

  • libsodium versions prior to commit ad3004e (fixed in 1.0.20-stable, 2025-12-31 build)
  • PyNaCl versions prior to 1.6.2 (bundles vulnerable libsodium)
  • Debian LTS packages tracked under the January 2026 advisory

Discovery Timeline

  • 2025-12-30 - Vulnerability disclosed on the 00f.net blog
  • 2025-12-31 - Upstream fix committed to libsodium (commit ad3004e)
  • 2025-12-31 - CVE-2025-69277 published to NVD
  • 2026-01-01 - PyNaCl 1.6.2 released with updated libsodium (PyNaCl fix)
  • 2026-01 - Debian LTS Announcement published
  • 2026-06-17 - Last updated in NVD database

Technical Details for CVE-2025-69277

Vulnerability Analysis

The defect sits in ge25519_is_on_main_subgroup() within src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c. The function multiplies the input point by the group order L and then checks whether the result is the neutral element. In extended projective (X, Y, Z, T) coordinates, the identity element satisfies both X == 0 and Y == Z. The pre-patch code only verified fe25519_iszero(pl.X), which is necessary but not sufficient. Small-order points can produce a result with X == 0 while Y != Z, so the check returned true and admitted points outside the main prime-order subgroup. This maps to [CWE-184] Incomplete List of Disallowed Inputs.

Root Cause

The validator conflated "X coordinate is zero" with "point is the identity." In Edwards curves using extended coordinates, the identity (0 : 1 : 1 : 0) requires both X == 0 and Y == Z. Omitting the second equality allowed the eight-torsion subgroup and related low-order points to pass validation.

Attack Vector

Exploitation requires an application that passes attacker-controlled points into crypto_core_ed25519_is_valid_point() and then uses the accepted point in a protocol that assumes prime-order subgroup membership. Standard libsodium high-level APIs such as crypto_sign are not affected because they do not depend on this check for their security proofs. The impact is limited to custom cryptographic constructions, which is reflected in the local attack vector and high complexity rating.

c
// Source: https://github.com/jedisct1/libsodium/commit/ad3004ec8731730e93fcfbbc824e67eadc1c1bae
// Patch to ge25519_is_on_main_subgroup: also verify Y == Z
 ge25519_is_on_main_subgroup(const ge25519_p3 *p)
 {
     ge25519_p3 pl;
+    fe25519    t;
 
     ge25519_mul_l(&pl, p);
 
-    return fe25519_iszero(pl.X);
+    fe25519_sub(t, pl.Y, pl.Z);
+
+    return fe25519_iszero(pl.X) & fe25519_iszero(t);
 }

Detection Methods for CVE-2025-69277

Indicators of Compromise

  • Presence of libsodium shared objects (libsodium.so.*) with build timestamps earlier than the 2025-12-31 1.0.20-stable release
  • PyNaCl installations reporting nacl.__version__ below 1.6.2
  • Application logs showing acceptance of Ed25519 points that later fail downstream signature or key-agreement checks

Detection Strategies

  • Inventory all software bundling libsodium, including statically linked binaries and language wrappers such as PyNaCl, libsodium-jni, and sodium-native.
  • Search source code for direct callers of crypto_core_ed25519_is_valid_point() and audit whether the accepted point is later used in custom scalar multiplication or key exchange logic.
  • Use software composition analysis (SCA) tooling to flag libsodium < 1.0.20-stable (2025-12-31 build) and PyNaCl < 1.6.2 across build pipelines.

Monitoring Recommendations

  • Track dependency manifests (requirements.txt, package.json, go.mod, Cargo.toml) in CI for pinned versions of libsodium or PyNaCl below the fixed releases.
  • Alert on new deployments of container images whose base layers include unpatched Debian, Ubuntu, or Alpine libsodium packages.
  • Correlate cryptographic protocol errors from application logs with the presence of vulnerable libsodium builds on the same host.

How to Mitigate CVE-2025-69277

Immediate Actions Required

  • Upgrade libsodium to the 1.0.20-stable build dated 2025-12-31 or later that includes commit ad3004e.
  • Upgrade PyNaCl to 1.6.2 or later, which bundles the fixed libsodium.
  • Rebuild and redeploy any statically linked binaries that embed libsodium.
  • Review custom cryptographic code that consumes Ed25519 points from untrusted sources and add explicit subgroup checks if patching is delayed.

Patch Information

The upstream libsodium fix is commit ad3004e, which adds the Y == Z check to ge25519_is_on_main_subgroup(). PyNaCl consumers should apply the version bump documented in the PyNaCl 1.6.2 changelog commit. Distribution updates are tracked in the Debian LTS Announcement.

Workarounds

  • Reject any external Ed25519 point that does not pass an application-level small-order check before invoking libsodium primitives.
  • Constrain the API surface so that untrusted input cannot reach crypto_core_ed25519_is_valid_point() until the patched library is deployed.
  • Prefer high-level libsodium APIs such as crypto_sign_verify_detached() and crypto_box_*, which are not affected by the incomplete subgroup check.
bash
# Verify installed versions against the fixed baselines
pkg-config --modversion libsodium    # expect >= 1.0.20
python -c "import nacl; print(nacl.__version__)"   # expect >= 1.6.2
apt-cache policy libsodium23         # confirm Debian/Ubuntu package includes the CVE-2025-69277 fix

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.