CVE-2026-82406
Klever-Go: Zombie-order theft: `Buy` missing `IsClaimed` guard in native marketplace
Klever-Go is the Go implementation of the Klever blockchain protocol. Prior to 1.7.20, the native marketplace function core/kapp/market/market.go Buy does not check IsClaimed before accepting a bid. A seller can use the Claim seller-accept branch to settle a resting-bid auction while leaving the claimed order loadable with a future EndTime and stale CurrentBid and CurrentBidder values. A later bidder can submit a higher bid, be debited, and cause the previous bidder to receive a refund even though the NFT has already been delivered. Because Claim and CancelOrder reject the later bidder when IsClaimed is true, the later bidder cannot obtain the NFT or recover the funds. This issue is fixed in version 1.7.20.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
7.1
Klever-Go: Zombie-order theft: `Buy` missing `IsClaimed` guard in native marketplace
Klever-Go is the Go implementation of the Klever blockchain protocol. Prior to 1.7.20, the native marketplace function core/kapp/market/market.go Buy does not check IsClaimed before accepting a bid. A seller can use the Claim seller-accept branch to settle a resting-bid auction while leaving the claimed order loadable with a future EndTime and stale CurrentBid and CurrentBidder values. A later bidder can submit a higher bid, be debited, and cause the previous bidder to receive a refund even though the NFT has already been delivered. Because Claim and CancelOrder reject the later bidder when IsClaimed is true, the later bidder cannot obtain the NFT or recover the funds. This issue is fixed in version 1.7.20.
- Record
CVE-2026-82406- CVSS 4.0
- 7.1 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-841
- Updated
- 2026-11-02
EUVDEUVD-2026-85573
7.1
Klever-Go is the Go implementation of the Klever blockchain protocol. Prior to 1.7.20, the native marketplace function core/kapp/market/market.go Buy does not check IsClaimed before accepting a bid. A seller can use the Claim seller-accept branch to settle a resting-bid auction while leaving the claimed order loadable with a future EndTime and stale CurrentBid and CurrentBidder values. A later bidder can submit a higher bid, be debited, and cause the previous bidder to receive a refund even though the NFT has already been delivered. Because Claim and CancelOrder reject the later bidder when IsClaimed is true, the later bidder cannot obtain the NFT or recover the funds. This issue is fixed in version 1.7.20.
- Record
EUVD-2026-85573- CVSS 4.0
- 7.1 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-26r5-4mm2-px5c
7.1
Klever-Go: Zombie-order theft: `Buy` missing `IsClaimed` guard in native marketplace
Location: core/kapp/market/market.go — Buy() (approx. L281–436)
Severity: High
The native marketplace enforces an IsClaimed guard in Claim (market.go:752), CancelOrder (market.go:1125), and orderEscrowAmount (market.go:251), but not in Buy.
Marketplace escrow is virtual: the market KApp account never custodies currency. A bid burns funds from the bidder (bidderAcc.SubFromBalance, ~L378), and refunds/payouts mint to the recipient (AddToBalance, e.g. the prior-bidder refund at ~L349). Soundness depends on each order's CurrentBid being paid out exactly once.
A seller can settle a resting-bid auction early via the seller-accept branch of Claim (~L776) → executeBuyMarket (~L656). That path sets IsClaimed=true, delivers the NFT, pays the seller, and re-saves the order (SetMarketOrder, ~L726) — but, unlike every other settle path, it does not reset EndTime (contrast immediate-buy Buy ~L416 and CancelOrder ~L1206), and no code path deletes the order. The result is a "zombie" order: already settled, yet still loadable with EndTime in the future and a stale CurrentBidder.
Because Buy has no IsClaimed guard, a new bidder can still Buy on that settled order (the bid guard at ~L317 only forces the new amount Y > CurrentBid X). The new bidder is debited Y; the prior bidder is refunded X (funded by the new bidder, not minted); the new bidder becomes CurrentBidder on an IsClaimed order and can then neither Claim (reverts on IsClaimed) nor CancelOrder (reverts on IsClaimed). Their funds are lost permanently.
Attack sequence (permissionless , anyone can create a sell order):
- Attacker (seller
S) creates a resting-bid auction (Price=0,ReservePrice>0) for an NFT and self-bidsXas bidderA(Sybil). SacceptsA's bid early viaClaim→ NFT goes toA(= attacker, keeps it),S(= attacker) collects the owner payout, order markedIsClaimed=truebut left "live".- Victim
BbidsY > Xon the still-live-looking auction viaBuy.Buyrefunds prior bidderAthe amountX(AddToBalance, L349) and burnsYfromB(SubFromBalance, L378). Bis nowCurrentBidderon a claimed order and can neitherClaimnorCancelOrder— both revert onIsClaimed.B'sYis unrecoverable;Xof it was siphoned toA;Y−Xis destroyed.
POC
package market
import (
"testing"
"github.com/klever-io/klever-go/common/mock"
"github.com/klever-io/klever-go/core/kapp"
"github.com/klever-io/klever-go/core/process/kda/kdautils"
"github.com/klever-io/klever-go/data/block"
"github.com/klever-io/klever-go/data/state"
"github.com/klever-io/klever-go/data/transaction"
"github.com/klever-io/klever-go/kapps"
"github.com/klever-io/klever-go/kvm/mock/stub"
"github.com/stretchr/testify/require"
)
// TestPoC_ZombieOrder_MissingIsClaimedGuardInBuy proves the fund-loss / theft
// vulnerability caused by `Buy` lacking the `IsClaimed` guard that `Claim`
// (market.go L752) and `CancelOrder` (market.go L1125) both enforce.
//
// Attack (attacker A == seller S, victim B):
// 1. S lists an NFT as an Auction with Price=0, ReservePrice=R (bids REST).
// 2. A places a resting bid X >= R via Buy (records CurrentBid/CurrentBidder,
// no settlement because Price==0).
// 3. S accepts the resting bid early via Claim's seller-accept branch (L776),
// which routes to executeBuyMarket: IsClaimed=true, NFT delivered to A,
// proceeds paid to S(=A). This settle path is the ONLY one that does NOT
// reset EndTime and does NOT delete the order -> the order becomes a live
// "zombie" (IsClaimed=true, EndTime in the future, still loadable).
// 4. Victim B calls Buy on the zombie order with Y > X. Buy has no IsClaimed
// guard, so it SUCCEEDS: B is debited Y, prior bidder A is "refunded" X
// (funded by B), and B becomes CurrentBidder on an already-claimed order.
// 5. B can NEITHER Claim…
- Record
GHSA-26r5-4mm2-px5c- CVSS 4.0
- 7.1 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-841
- Updated
- 2026-11-02
NVD
7.1
Klever-Go is the Go implementation of the Klever blockchain protocol. Prior to 1.7.20, the native marketplace function core/kapp/market/market.go Buy does not check IsClaimed before accepting a bid. A seller can use the Claim seller-accept branch to settle a resting-bid auction while leaving the claimed order loadable with a future EndTime and stale CurrentBid and CurrentBidder values. A later bidder can submit a higher bid, be debited, and cause the previous bidder to receive a refund even though the NFT has already been delivered. Because Claim and CancelOrder reject the later bidder when IsClaimed is true, the later bidder cannot obtain the NFT or recover the funds. This issue is fixed in version 1.7.20.
- Record
CVE-2026-82406- CVSS 4.0
- 7.1 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Weakness
- CWE-841
- Updated
- 2026-11-02
OSV
7.1
Klever-Go: Zombie-order theft: `Buy` missing `IsClaimed` guard in native marketplace
Klever-Go is the Go implementation of the Klever blockchain protocol. Prior to 1.7.20, the native marketplace function core/kapp/market/market.go Buy does not check IsClaimed before accepting a bid. A seller can use the Claim seller-accept branch to settle a resting-bid auction while leaving the claimed order loadable with a future EndTime and stale CurrentBid and CurrentBidder values. A later bidder can submit a higher bid, be debited, and cause the previous bidder to receive a refund even though the NFT has already been delivered. Because Claim and CancelOrder reject the later bidder when IsClaimed is true, the later bidder cannot obtain the NFT or recover the funds. This issue is fixed in version 1.7.20.
- Record
CVE-2026-82406- CVSS 4.0
- 7.1 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-841
- Updated
- 2026-11-02
OSVGHSA-26r5-4mm2-px5c
7.1
Klever-Go: Zombie-order theft: `Buy` missing `IsClaimed` guard in native marketplace
Location: core/kapp/market/market.go — Buy() (approx. L281–436)
Severity: High
The native marketplace enforces an IsClaimed guard in Claim (market.go:752), CancelOrder (market.go:1125), and orderEscrowAmount (market.go:251), but not in Buy.
Marketplace escrow is virtual: the market KApp account never custodies currency. A bid burns funds from the bidder (bidderAcc.SubFromBalance, ~L378), and refunds/payouts mint to the recipient (AddToBalance, e.g. the prior-bidder refund at ~L349). Soundness depends on each order's CurrentBid being paid out exactly once.
A seller can settle a resting-bid auction early via the seller-accept branch of Claim (~L776) → executeBuyMarket (~L656). That path sets IsClaimed=true, delivers the NFT, pays the seller, and re-saves the order (SetMarketOrder, ~L726) — but, unlike every other settle path, it does not reset EndTime (contrast immediate-buy Buy ~L416 and CancelOrder ~L1206), and no code path deletes the order. The result is a "zombie" order: already settled, yet still loadable with EndTime in the future and a stale CurrentBidder.
Because Buy has no IsClaimed guard, a new bidder can still Buy on that settled order (the bid guard at ~L317 only forces the new amount Y > CurrentBid X). The new bidder is debited Y; the prior bidder is refunded X (funded by the new bidder, not minted); the new bidder becomes CurrentBidder on an IsClaimed order and can then neither Claim (reverts on IsClaimed) nor CancelOrder (reverts on IsClaimed). Their funds are lost permanently.
Attack sequence (permissionless , anyone can create a sell order):
- Attacker (seller
S) creates a resting-bid auction (Price=0,ReservePrice>0) for an NFT and self-bidsXas bidderA(Sybil). SacceptsA's bid early viaClaim→ NFT goes toA(= attacker, keeps it),S(= attacker) collects the owner payout, order markedIsClaimed=truebut left "live".- Victim
BbidsY > Xon the still-live-looking auction viaBuy.Buyrefunds prior bidderAthe amountX(AddToBalance, L349) and burnsYfromB(SubFromBalance, L378). Bis nowCurrentBidderon a claimed order and can neitherClaimnorCancelOrder— both revert onIsClaimed.B'sYis unrecoverable;Xof it was siphoned toA;Y−Xis destroyed.
POC
package market
import (
"testing"
"github.com/klever-io/klever-go/common/mock"
"github.com/klever-io/klever-go/core/kapp"
"github.com/klever-io/klever-go/core/process/kda/kdautils"
"github.com/klever-io/klever-go/data/block"
"github.com/klever-io/klever-go/data/state"
"github.com/klever-io/klever-go/data/transaction"
"github.com/klever-io/klever-go/kapps"
"github.com/klever-io/klever-go/kvm/mock/stub"
"github.com/stretchr/testify/require"
)
// TestPoC_ZombieOrder_MissingIsClaimedGuardInBuy proves the fund-loss / theft
// vulnerability caused by `Buy` lacking the `IsClaimed` guard that `Claim`
// (market.go L752) and `CancelOrder` (market.go L1125) both enforce.
//
// Attack (attacker A == seller S, victim B):
// 1. S lists an NFT as an Auction with Price=0, ReservePrice=R (bids REST).
// 2. A places a resting bid X >= R via Buy (records CurrentBid/CurrentBidder,
// no settlement because Price==0).
// 3. S accepts the resting bid early via Claim's seller-accept branch (L776),
// which routes to executeBuyMarket: IsClaimed=true, NFT delivered to A,
// proceeds paid to S(=A). This settle path is the ONLY one that does NOT
// reset EndTime and does NOT delete the order -> the order becomes a live
// "zombie" (IsClaimed=true, EndTime in the future, still loadable).
// 4. Victim B calls Buy on the zombie order with Y > X. Buy has no IsClaimed
// guard, so it SUCCEEDS: B is debited Y, prior bidder A is "refunded" X
// (funded by B), and B becomes CurrentBidder on an already-claimed order.
// 5. B can NEITHER Claim…
- Record
GHSA-26r5-4mm2-px5c- CVSS 4.0
- 7.1 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-841
- Updated
- 2026-11-02
OSVGO-2026-6584 No score
Klever-Go: Zombie-order theft: `Buy` missing `IsClaimed` guard in native marketplace in github.com/klever-io/klever-go
Klever-Go: Zombie-order theft: Buy missing IsClaimed guard in native marketplace in github.com/klever-io/klever-go
- Record
GO-2026-6584- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
github.com/klever-io/klever-goGo |
through 1.7.19 | 1.7.20 |
github.com/klever-io/klever-goGo |
before 1.7.20 | 1.7.20 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-82406 is a high vulnerability (CVSS 7.1) in Klever-io Klever-go, published September 23, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.43%, the 37th percentile. Fixed in github.com/klever-io/klever-go 1.7.20.
References
github.com/klever-io/klever-go/security/advisories/GHSA-26r5-4mm2-px5c
github.com/klever-io/klever-go/pull/16
github.com/klever-io/klever-go/commit/063bb3ed98f9a84a4b1f7286680613a5fc3c91b2
github.com/klever-io/klever-go/releases/tag/v1.7.20
github.com/advisories/GHSA-26r5-4mm2-px5c
github.com/CVEProject/cvelistV5/tree/main/cves/2026/82xxx/CVE-2026-82406.json
nvd.nist.gov/vuln/detail/CVE-2026-82406
github.com/klever-io/klever-go
Left out here: the rest of 2 source descriptions. The JSON record has them.