Advisory Database
  • Advisories
  • Dependency Scanning
  1. golang
  2. ›
  3. github.com/klever-io/klever-go
  4. ›
  5. CVE-2026-82405

CVE-2026-82405: Klever-Go Account takeover: `kleverUpdateAccountPermission` authorizes on attacker-controlled `RecipientAddr` instead of the authenticated caller

September 23, 2026

The VM built-in function KleverUpdateAccountPermission (registered always-active, creator.go:381-390 / core/vmconstants.go:234) rewrites an account’s entire permission set. Its authorization check uses vmInput.RecipientAddr attacker-controlled instead of the authenticated vmInput.CallerAddr. The sibling handler kleverChangeOwnerAddress.go:86 uses vmInput.CallerAddr correctly, so the safe pattern exists in-repo; this handler deviates. The native transaction path (txProcess.go:833) is safe it uses tx.GetSender().

Mechanism:

  1. Wrong variable: CallerAddr is never referenced in the handler; auth is contractHasValidPermission(target.GetPermissions(), RecipientAddr), which returns true if RecipientAddr is a signer with Weight >= Threshold in the target account’s permissions and the permission grants UpdateAccountPermissionContractType.
  2. RecipientAddr is attacker-controlled: when a contract calls a built-in via ExecuteOnDestContextWithTypedArgs (baseOps.go:1967), prepareIndirectContractCallInput (baseOps.go:2485) sets RecipientAddr = destination (contract-chosen) and CallerAddr = the calling contract. The blockchain hook (blockChainHook.go:454/467) dispatches on input.Function and passes the input through unchanged; no guard forces RecipientAddr == CallerAddr and there is no SC-destination validation on this path.
  3. Self-signer default satisfies the check: createDefaultOwnerPermission (accounts.go:1848) makes an account its own signer (weight 1, threshold 1, Owner type), and CheckPermissionGrantedForContracts returns true for Owner, so contractHasValidPermission(V.perms, V) == true. (More generally, RecipientAddr can be set to any of V’s signer addresses meeting threshold all public on-chain.) Accounts with no stored permissions have empty GetPermissions() and are immune.
  4. Overwrite is unrestricted: UpdatePermission(V, attackerContract) (accounts.go:1863) replaces V’s permission set with attacker-supplied signers; if the attacker supplies an Owner-type permission, no default is appended and V’s prior control is fully evicted.

References

  • gist.github.com/mabdullah22/a41f90aa5ba86bbebf121f739bd5f5e9
  • github.com/advisories/GHSA-97cv-x867-6xhm
  • github.com/klever-io/klever-go/commit/c58740eb74d7ee8f07db1e18a7d6214b5559ba32
  • github.com/klever-io/klever-go/releases/tag/v1.7.20
  • github.com/klever-io/klever-go/security/advisories/GHSA-97cv-x867-6xhm
  • nvd.nist.gov/vuln/detail/CVE-2026-82405

Code Behaviors & Features

Detect and mitigate CVE-2026-82405 with GitLab Dependency Scanning

Secure your software supply chain by verifying that all open source dependencies used in your projects contain no disclosed vulnerabilities. Learn more about Dependency Scanning →

Affected versions

All versions before 1.7.20

Fixed versions

  • 1.7.20

Solution

Upgrade to version 1.7.20 or above.

Impact 8.8 HIGH

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Learn more about CVSS

Weakness

  • CWE-863: Incorrect Authorization

Source file

go/github.com/klever-io/klever-go/CVE-2026-82405.yml

Spotted a mistake? Edit the file on GitLab.

  • Site Repo
  • About GitLab
  • Terms
  • Privacy Statement
  • Contact

Page generated Mon, 12 Oct 2026 12:18:40 +0000.