GitHub Advisoryadvisory · Go

GHSA-p7gw-2pcp-5pf8 Klever: Marketplace settlement mints KLV when referral % + royalty % exceed the bid (negative seller share silently skipped)

CRITICAL Published 2026-08-28 Modified 2026-08-28 Official page ↗
Aliases
CVE-2026-54754
Ecosystem
Go
Packages
github.com/klever-io/klever-go
Severity
Critical
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:H
Weaknesses
CWE-191, CWE-367, CWE-682
Reviewed
2026-08-28

Affected packages

• Go github.com/klever-io/klever-go: < 1.7.19 → fixed in 1.7.19

Description

Summary When a marketplace order is settled (`MarketBuy` / `BuyItNow`, and auction `Claim`), the buyer's payment is split three ways — referral, royalties, and the seller (market-order owner) remainder: ``` marketOwnerAmount = CurrentBid − referralAmount − royaltiesAmount ``` Referral and royalties are paid out unconditionally, but the seller remainder is only paid when positive (`computeMarketOwnerAmount` returns `Ok` and pays nothing when the amount is ` bid`, the surplus `(referralAmount + royaltiesAmount − bid)` is minted. 2. The combined ≤100% invariant is enforced only at listing time `Sell` (`market.go:908`) correctly rejects a listing whose combined cut exceeds 100%: ```go if asset.Royalties.MarketPercentage + marketplace.ReferralPercentage > core.HundredPercent { return transaction.Transaction_ParameterInvalid, common.ErrInvalidValue } ``` …and snapshots referral into the order, but not royalty (`market.go:997-998`): ```go marketOrder := &kapps.MarketOrderData{ // ... ReferralPercentage: marketplace.ReferralPercentage, // snapshotted RoyaltiesFixedDeposit: asset.Royalties.MarketFixed, // snapshotted // NOTE: asset.Royalties.MarketPercentage is NOT snapshotted -> read live at buy } ``` `MarketOrderData` has no field for the royalty percentage (`kapps/market.pb.go`), so settlement always re-reads it live from the (mutable) asset. 3. Royalty % is mutable after listing `core/kapp/kda/trigger.go` — `handleUpdateRoyaltiesNFTandSFT` (L613+) lets the asset owner overwrite `asset.Royalties.MarketPercentage` (L670) with only a per-field ` The shipped emergency-guard source documents this exact vector: > *"The royalty percentage is read live at buy time, so a listing made now can be weaponised later > via UpdateRoyalties."* (`common/emergencyGuard.go`) Net effect: `referralAmount + royaltiesAmount = bid + bid = 2·bid`; `marketOwnerAmount = −bid` (skipped); `bid` KLV minted per settlement, paid to attacker-controlled addresses. --- Proof of Concept A. Committed regression test (deterministic, runnable today) `core/kapp/market/market_test.go` — `TestMarketKApp_ExecuteBuyMarket_RoyaltyReferralInflation`. It builds an order with `ReferralPercentage = 100%` and an asset with `MarketPercentage = 100%` (the attacker is both the referral and the royalty address), then settles a `bid` of `25,600,000 KLV` (`25600000000000` base units): ```bash go test ./core/kapp/market/ -run TestMarketKApp_ExecuteBuyMarket_RoyaltyReferralInflation -v ``` • `FixDisabled_MintsKLVFromThinAir`: settlement returns `Ok`; the attacker address ends with `2·bid` credited while only `bid` was paid in — i.e. `bid` KLV minted. • `FixEnabled_RejectsInflation`: with `FixMarketBuyOverflow` on, settlement returns `Transaction_AmountInvalid` and the attacker balance stays `0` — no payout runs. B. End-to-end on a local node (the real attack path) A single-node local network is sufficient. The exploit is four transactions from one ordinary funded account; nothing privileged is required. 1. Create an NFT collection you own, with `royalties.marketPercentage = 0` and a royalties address you control. 2. Create a marketplace with `referralPercentage = 10000` (100%) and a referral address you control (`CreateMarketplace`). 3. List one NFT for sale (`Sell`) on that marketplace. The `Sell` check passes because `0 (royalty) + 10000 (referral) = 10000 = HundredPercent`. The order snapshots `ReferralPercentage = 10000`. 4. Raise the royalty on the asset to 100% (`AssetTrigger / UpdateRoyalties`, `marketPercentage = 10…

Related

Alias · CVE (1)

  • CVE-2026-54754 Klever-Go is the Go implementation of the Klever blockchain protocol. vulnerability

Weakness · CWE (3)

  • CWE-191 Integer Underflow (Wrap or Wraparound) weakness
  • CWE-367 Time-of-check Time-of-use (TOCTOU) Race Condition weakness
  • CWE-682 Incorrect Calculation weakness

References