Listen to this Post
The Klever blockchain implements a BDN (Boneh-Drijvers-Neven) BLS multi-signature scheme over the BLS12-381 curve to finalize blocks. The implementation resides in `crypto/signing/mcl/multisig/bls.go` and utilizes the `herumi/bls-go-binary` library. The critical flaw stems from incomplete initialization: the library is configured with only `bls.Init(bls.BLS12_381)` without enabling order-verification flags. This means the `Deserialize` function does not enforce prime-order-subgroup membership when processing public keys. Subgroup safety relies entirely on explicit `IsValidOrder()` calls within wrapper functions.
Runtime validator registration through `validators.Register` at `core/kapp/validators/validators.go:201` stores submitted 96-byte BLSPublicKey values via `SetBLSPublicKey` without performing curve checks, subgroup validation, or proof-of-possession verification. The `CreateValidatorContract` carries the key but includes no signature proving key ownership. Code analysis confirms no proofOfPossession, VerifyProof, or `BLSSignature` verification exists anywhere in core/kapp/validators/.
The `CheckPublicKeyValid` function, which performs `IsValid && IsValidOrder && !IsZero` checks, runs exclusively at genesis through genesis/checking/nodesSetupChecker.go:73, not during runtime registration or updates. When a validator with a malformed key is selected into a consensus group, every in-group node calls `MultiSigner().Reset(groupPubKeys, selfIndex)` at slot start via core/consensus/slot/bls/subslotStartSlot.go:165. This deserializes all group keys through PublicKeyFromByteArray, causing herumi `Deserialize` to deterministically fail on the malformed key, triggering SetSlotCanceled(true). The verification side at `core/consensus/…/headerSignatureVerify.go:123` fails identically, preventing block production for that round.
DailyCVE Form
Platform: Klever Blockchain
Version: All versions
Vulnerability: Malformed BLS keys
Severity: High (Critical small)
date: 2026-09-23
Prediction: Next epoch fork
What Undercode Say
Analytics
Check validator registration code:
grep -n "SetBLSPublicKey" core/kapp/validators/validators.go sed -n '195,215p' core/kapp/validators/validators.go
Examine BLS initialization:
cat crypto/signing/mcl/multisig/bls.go | grep -A5 "bls.Init"
Verify missing proof-of-possession:
grep -r "proofOfPossession|VerifyProof|BLSSignature" core/kapp/validators/
Check genesis-only validation:
sed -n '70,80p' genesis/checking/nodesSetupChecker.go
Test key validation:
// TestCheckPublicKeyValid demonstrates validation logic
func TestCheckPublicKeyValid(t testing.T) {
malformedKey := make([]byte, 96)
// Fill with arbitrary bytes
for i := range malformedKey {
malformedKey[bash] = byte(i % 256)
}
valid := CheckPublicKeyValid(malformedKey)
// Expected: false, but registration bypasses this
}
Exploit: (Educational Purposes!)
Step 1: Stake minimum validator amount and submit malformed 96-byte BLSPublicKey (arbitrary bytes not forming valid G2 point). Registration succeeds due to missing runtime validation.
Step 2: Once eligible and selected into consensus group, observe slot cancellation as all nodes fail deserialization:
Monitor slot cancellation events journalctl -u klever-node | grep "SetSlotCanceled|slot canceled"
Step 3: Repeat with multiple validator registrations to amplify liveness degradation across consensus rounds.
Protection: from this CVE
Enforce `CheckPublicKeyValid` (curve + prime-order subgroup + non-zero) at runtime validator registration and config-update. Implement proof-of-possession requiring BLS signature over validator’s own key/identity. Gate stricter validation behind epoch fork flag for reprocessing consistency. Apply validation at `validators.Register` and update paths:
func (k Keeper) Register(ctx sdk.Context, validator Validator) error {
if !CheckPublicKeyValid(validator.BLSPublicKey) {
return ErrInvalidBLSPublicKey
}
// Additional PoP verification
return k.registerValidator(ctx, validator)
}
Impact
Every consensus round containing the malformed-key validator results in a missed slot. One eligible bad-key validator poisons approximately `groupSize / eligibleSet` fraction of rounds, causing sustained liveness degradation. Where consensus group equals eligible set (small or early-stage networks), this becomes full chain halt. Attack cost is minimum validator stake, permissionless, and repeatable with no fork flag gating the missing validation. Severity scales down to fractional missed-slot/throughput-degradation on large validator sets where bad validator is occasionally in active group.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

