From 9eee6359e0bb55ba5d141213fb414d990159750f Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:44:03 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[MEDIUM]=20?= =?UTF-8?q?Enhance=20Ed25519=20signature=20verification=20strictness?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🚨 Severity: MEDIUM 💡 Vulnerability: Ed25519 signatures were being verified using the standard `.verify()` method. Standard verification is susceptible to signature malleability issues if torsion components or non-canonical scalars are present. 🎯 Impact: While Ed25519 is generally secure, accepting malleable signatures can cause issues in systems that rely on unique signatures for identifier derivation or consensus checks. 🔧 Fix: Updated standard `.verify()` calls to `.verify_strict()` from `ed25519-dalek`. This method strictly complies with RFC 8032 and prevents signature malleability by rejecting non-canonical signatures. Removed unused `Verifier` traits as well. ✅ Verification: Ensure the test suite passes with `cargo test` as normal compliant signatures pass strict verification. Co-authored-by: euxaristia <25621994+euxaristia@users.noreply.github.com> --- .jules/sentinel.md | 0 crates/gitlawb-attest/src/attestation.rs | 5 +++-- crates/gitlawb-core/src/identity.rs | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 .jules/sentinel.md diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 00000000..e69de29b diff --git a/crates/gitlawb-attest/src/attestation.rs b/crates/gitlawb-attest/src/attestation.rs index 5adc7411..a2eae0a4 100644 --- a/crates/gitlawb-attest/src/attestation.rs +++ b/crates/gitlawb-attest/src/attestation.rs @@ -16,7 +16,7 @@ //! by exact match. use base64::{engine::general_purpose::URL_SAFE_NO_PAD as B64U, Engine}; -use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey}; +use ed25519_dalek::{Signature, Signer, SigningKey, VerifyingKey}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use crate::error::{Error, Result}; @@ -111,7 +111,8 @@ impl Attestation { .try_into() .map_err(|_| Error::Signature("signature must be 64 bytes".to_string()))?; let sig = Signature::from_bytes(&sig_bytes); - vk.verify(&bytes, &sig) + // Sentinel: Use verify_strict to prevent signature malleability (strict RFC 8032 compliance) + vk.verify_strict(&bytes, &sig) .map_err(|e| Error::Signature(format!("ed25519: {e}")))?; Ok(vk) diff --git a/crates/gitlawb-core/src/identity.rs b/crates/gitlawb-core/src/identity.rs index 511e1203..7f1defc0 100644 --- a/crates/gitlawb-core/src/identity.rs +++ b/crates/gitlawb-core/src/identity.rs @@ -78,10 +78,11 @@ impl Keypair { /// Verify an Ed25519 signature. pub fn verify(verifying_key: &VerifyingKey, msg: &[u8], sig_bytes: &[u8; 64]) -> Result<()> { - use ed25519_dalek::Verifier; + let sig = Signature::from_bytes(sig_bytes); + // Sentinel: Use verify_strict to prevent signature malleability (strict RFC 8032 compliance) verifying_key - .verify(msg, &sig) + .verify_strict(msg, &sig) .map_err(|_| Error::SignatureInvalid) }