How This Was Found
During Olympia upgrade preparation, the ETC core team needed Core-Geth as a reference client alongside Besu and Nethermind — both carrying ETC overlays for cross-client testing but not recommended for production. Core-Geth was the only existing ETC client at the time. That work confirmed what the commit history showed: the etclabscore/core-geth repository had not shipped a code release since v1.12.20 on 10 June 2024 — a 21-month gap. Multiple CVEs had accumulated unpatched, and the client was still shipping binaries built on Go 1.21, a runtime that reached end-of-life in August 2024.
Security disclosures sent to the upstream maintainer in February 2025 received no response. The last substantive upstream commit was the v1.12.20 release itself; the final commit of any kind was a GitHub Actions CI update on 23 January 2025. With Olympia requiring a reliable, patched client for network continuity, the ETC core development team brought Core-Geth forward under the ethereumclassic organisation, applied all known patches, upgraded the Go toolchain to 1.26, and released Core-Geth v1.13.0.
CVE Gap Analysis
The following vulnerabilities were present in etclabscore/core-geth at v1.12.20. All are patched in ethereumclassic/core-geth v1.13.0.
Missing IsOnCurve check in UnmarshalPubkey — off-curve secp256k1 points pass deserialization without error, causing invalid results in any downstream ECDSA or ECDH operation.
8e40b7e41ECIES Decrypt() length check used +1 instead of +params.BlockSize (16). Crafted RLPx auth messages with undersized ECIES payloads cause an out-of-bounds read — remote crash during P2P handshake, no authentication required.
dc73f2e4fECIES GenerateShared() accepted unvalidated ephemeral public keys into ECDH. A MAC-oracle attack using repeated unauthenticated RLPx handshakes can leak bits of the node's static P2P private key.
2d3528803IsOnCurve() did not verify coordinates are strictly less than the curve prime P. Out-of-field coordinates satisfy the naive curve equation via modular arithmetic and bypass the validity gate, leading to undefined scalar multiplication results.
2d3528803P2P message handler validated payload size (10 MiB cap) but not the number of RLP list items. A crafted header declaring millions of tiny items allocates per-item memory before validation — remote OOM crash via a single P2P message from any connected peer.
5d0cb8b34CVE-2026-22868MEDIUMPATCHEDKZG blob proof validation DoS — invalid proofs trigger full expensive cryptographic verification without disconnecting the offending peer, allowing sustained CPU exhaustion from any connected peer.
1419c5310GraphQL Depth DoSMEDIUMPATCHEDNo query depth or complexity limit on the GraphQL endpoint (--graphql flag). Deeply nested queries exhaust CPU and memory. Compounded by GHSA-mh3m-8c74-74xh — a bug in graphql-go v1.3.0 where MaxDepth was silently non-functional.
6c2d383faGo Runtime End-of-Life
The upstream Core-Geth v1.12.20 release was built with Go 1.21, which reached end-of-life in August 2024. Go's release policy provides security patches only for the two most recent major versions. As of March 2026, Go 1.21 had been unsupported for 19 months, leaving the runtime's standard library (net/http, crypto/tls, encoding) unpatched across that window.
Core-Geth v1.13.0 at ethereumclassic/core-geth builds on Go 1.26 (current stable). The upgrade proceeded in two steps: Go 1.21 → 1.24 (removing the incompatible fjl/memsize dependency and fixing go vet format errors), then Go 1.24 → 1.26 (updating all golang.org/x/ dependencies for compatibility). The blst cryptography library was simultaneously upgraded from v0.3.11 to v0.3.16. Commit: 8385cf8e8.
Release Timeline
Core-Geth v1.12.20 released at etclabscore/core-geth
Final upstream release — no code releases after this date
Go 1.21 reaches end-of-life
Build toolchain unsupported, runtime CVEs accumulate unpatched
Last upstream commit — GitHub Actions CI update
No code changes; repository effectively frozen
Security disclosures sent to upstream maintainer
No response received
All six CVEs patched at ethereumclassic/core-geth
CVE-2025-24883, CVE-2026-22862, CVE-2026-26315, CVE-2026-26314, CVE-2026-22868, CVE-2026-26313
Go toolchain upgraded 1.21 → 1.26
Commit 8385cf8e8; blst v0.3.11 → v0.3.16
Core-Geth v1.13.0 released at ethereumclassic/core-geth
All CVEs patched; Go 1.26; Olympia-ready
Risk Assessment
Any peer on the ETC network can crash a node with a single crafted P2P message — no authentication, no prior relationship required.
Mitigation: Item count validation added in v1.13.0. Commit 5d0cb8b34.
Repeated unauthenticated RLPx handshakes with crafted ephemeral keys can leak bits of the node's static private key across the 21-month exposure window.
Mitigation: Patched in v1.13.0. Rotate the P2P node key (rm <datadir>/geth/nodekey) as a precaution on long-running nodes.
Off-by-fifteen length check in ECIES Decrypt() allows undersized ciphertext to trigger an out-of-bounds read during the RLPx handshake.
Mitigation: Patched in v1.13.0. Commit dc73f2e4f.
Upstream Core-Geth shipped on Go 1.21, which reached EOL in August 2024. Runtime vulnerabilities in net/http, crypto/tls, and encoding accumulated unpatched for 19 months.
Mitigation: Core-Geth v1.13.0 builds on Go 1.26 (current stable as of March 2026).
No response to security disclosures sent February 2025. The etclabscore/core-geth organisation received no substantive code commit after June 2024.
Mitigation: Client transferred to the ethereumclassic org. Olympia multi-client architecture (Fukuii, Core-Geth, Besu) eliminates single-client dependency.
The gap between v1.12.20 (June 2024) and v1.13.0 (March 2026) is the longest maintenance gap in ETC network history.
Mitigation: Protocol-funded maintenance path established via ECIP-1112 treasury.
The March 2026 Attack
On 18 March 2026, CVE-2026-22862 was actively exploited against the ETC mainnet classic bootnodes ams3 and sfo3. Malicious P2P traffic sent crafted auth messages with undersized ECIES payloads, crashing each node on inbound handshake attempts. Because the crash occurred in listenLoop, the node process exited and restarted under the service manager — only to crash again on the next malicious connection, producing an automated crash-loop. Bootnode sfo3 accumulated 805+ restart cycles on v1.12.20 before the patch was deployed.
panic: runtime error: makeslice: len out of range
goroutine 42797 [running]:
github.com/ethereum/go-ethereum/crypto/ecies.symDecrypt(...)
crypto/ecies/ecies.go:224
github.com/ethereum/go-ethereum/crypto/ecies.(*PrivateKey).Decrypt(...)
crypto/ecies/ecies.go:322
github.com/ethereum/go-ethereum/p2p/rlpx.(*handshakeState).readMsg(...)
p2p/rlpx/rlpx.go:612
github.com/ethereum/go-ethereum/p2p/rlpx.(*handshakeState).runRecipient(...)
p2p/rlpx/rlpx.go:415
github.com/ethereum/go-ethereum/p2p/rlpx.(*Conn).Handshake(...)
p2p/rlpx/rlpx.go:308
github.com/ethereum/go-ethereum/p2p.(*Server).listenLoop.func2()
p2p/server.go:921Stack trace from issue #692. PR #694 (v1.12.21) was opened and merged in 5 hours — the first code activity from the upstream maintainer in 14 months.
Postmortem: Public Evidence Trail
The following issues and PRs at etclabscore/core-geth form a linkable evidence trail. Each was a missed opportunity to prevent the March 2026 attack.
geth version-check to surface CVE advisories
Filed by one of the core maintainers five years before the attack: add CVE tracking to version-check. Had it been implemented, the 2025–2026 advisories would have surfaced in every node operator's log.
Merge go-ethereum v1.14
Community maintainer prepared a full v1.14 merge, noted it was "ready for merge." Remained open through the March 2026 emergency.
Dependabot: bump golang.org/x/crypto 0.17→0.31
Automated tooling upgraded the exact dependency affected by CVE-2026-22862 — later exploited in production. Auto-closed when a newer version superseded it. No human reviewed it.
Support go 1.24 — includes CVE-2025-24883 fix
Community member @tornadocontrib explicitly referenced CVE-2025-24883 with a link to the advisory. Available for 9 months before the attack. Closed when contributor deleted their fork. No review, no response.
Automated: remove unresponsive bootnodes
Bootnode health check flagged deployed ETC bootnodes as unresponsive — some already experiencing intermittent crash-loops from early exploit probing.
Security vulnerabilities in go-ethereum affecting core-geth
Ledger security researcher publicly disclosed CVE-2025-24883, CVE-2026-22862, and CVE-2026-22868 on 4 February 2026. First maintainer response: 18 March 2026 — the day the attack began.
Release v1.12.21 ("Aegis") — emergency ECIES patch
Forced by active attack on bootnodes ams3 and sfo3. First code activity from @diega in 14 months. Three additional CVEs remained unaddressed.
Release v1.12.22 ("Hermes") — remaining CVE backports
Merged in 60 seconds with no pre-merge review. Drawn from White B0x work publicly available since 20–21 March without attribution. Go 1.21 EOL toolchain left unchanged.
Incorrect RPC eth_syncing response with v1.12.22
Regression introduced by the rushed v1.12.22: highestBlock reported incorrectly. Services relying on eth_syncing for sync status receive wrong data.
Structural Failures
Five independent structural failures — any one of which, if addressed, would have been sufficient to prevent the March 2026 attack.
1. No CVE Tracking Infrastructure
Issue #292 (2021) requested built-in CVE tracking in version-check. Never implemented. Operators had no automated signal that their client was exposed — they had to independently monitor the go-ethereum advisory database.
2. Automated Security PRs Unreviewed
Dependabot filed security bump PRs for golang.org/x/crypto and golang.org/x/net across January–April 2025, all unreviewed or auto-closed. PR #683 explicitly cited CVE-2025-24883 by name and was ignored for 9 months.
3. Single Point of Human Authority
@diega was the only person with merge access willing to cut releases. One community maintainer had a ready-to-merge PR (#649) but no merge rights. No governance path for security-critical changes without a non-reviewing approver.
4. Go Toolchain Lock-in
The fjl/memsize dependency was incompatible with Go 1.22+, locking the client to Go 1.21 (EOL August 2024). Three community PRs attempted partial fixes. The lock-in was known; it was not prioritised until it became a crisis.
5. Emergency Releases without Pre-release Testing
v1.12.21 was cut 5 hours after the PR opened; v1.12.22 was merged in 60 seconds. The rushed process introduced the eth_syncing regression (issue #697, still open).
Why Fukuii Is the ETC Client
The Core-Geth security failure was not a one-off — it was the predictable outcome of a Go-based client built outside the Ethereum Classic ecosystem, maintained under a corporate structure that has since wound down. Fukuii is the ETC-native execution client built from the ground up for Ethereum Classic:
- ETC-native from inception — Not a fork of go-ethereum. Does not share the Go toolchain, the go-ethereum P2P stack, or any of the code paths that were vulnerable in Core-Geth.
- Built on Scala 3 / Apache Pekko — a modern, type-safe stack with actor-based concurrency designed for long-term maintainability.
- Primary maintainer: Chippr Robotics — the core development team responsible for Fukuii's ongoing protocol implementation, security maintenance, and Olympia readiness.
- Security work by White B0x — one of the active teams building Fukuii. White B0x authored the Core-Geth v1.13.0 security patches (all CVEs, Go 1.26 upgrade, Olympia alignment) as part of the cross-client validation that Fukuii's development requires. The same team that found and fixed the vulnerabilities is building the client that replaces Core-Geth.
- Olympia-ready — Fukuii is the lead implementation for the Olympia hard fork (ECIP-1111/1112/1121/1122). Core-Geth v1.13.0 and Besu (ETC overlay) serve as cross-client validation references; Fukuii is the production target.
- Protocol-funded maintenance — ECIP-1112 establishes a protocol treasury funded by Olympia's EIP-1559 basefee revenue, providing Fukuii's ongoing development with a maintenance path that is not dependent on any single corporate entity.
Prior Maintainers
Core-Geth is a fork of multi-geth, originally created and maintained by Wei Tang (@sorpaas). Multi-geth was the first multi-network go-ethereum fork with first-class ETC support, and its chain configuration architecture is the direct ancestor of core-geth.
The core-geth fork was then developed by ETC Labs until they left the ETC ecosystem in 2022. ETC Cooperative-paid staff maintained the client through the Spiral hard fork up until announcing maintenance mode for the client in December 2024:
- Isaac Ardis (@meowsbits) — primary architect and long-term maintainer
- Diego López León (@diega) — release manager; cut the v1.12.20 release
- Chris Ziogas (@ziogaschr) — contributor and maintainer
Network Migration Path
Core-Geth v1.13.x is the final stable release series of this client. The ETC network is migrating to Fukuii (github) as the primary ETC-native execution client. Core-Geth will continue to be maintained through the Olympia upgrade cycle to ensure a stable transition, but operators should plan their migration to Fukuii beyond that point.
If you are running any v1.12.x release, upgrade to v1.13.0 immediately. The v1.12 series is affected by all six vulnerabilities documented in this audit and is not supported for the Olympia network upgrade.
Recommendations
- Node operators (v1.12.x): Update to Core-Geth v1.13.0 from github.com/ethereumclassic/core-geth. Nodes running etclabscore/core-geth v1.12.20 or earlier are exposed to remote crash (CVE-2026-26313, CVE-2026-22862) and potential key-oracle attacks (CVE-2026-26315), and will not be compatible with the Olympia hard fork.
- Long-running nodes: Rotate your P2P node key as a precaution against CVE-2026-26315 exposure:
rm <datadir>/geth/nodekey - Infrastructure providers and exchanges: Treat the upgrade to v1.13.0 as a security-critical patch, not a routine version bump. Begin planning migration to Fukuii for post-Olympia operation.
- Multi-client operation: Run multiple client implementations (Fukuii, Core-Geth, Besu) for cross-validation and redundancy during the transition.
- GraphQL endpoints: Verify v1.13.0 is deployed before re-opening the
--graphqlport on public-facing nodes.
Methodology
These findings emerged from Olympia upgrade preparation. Core-Geth was required as a reference client alongside Besu and Nethermind, both of which carry ETC overlays for cross-client testing and are not recommended for production use. Fukuii is the only ETC-native production client and is built on Scala 3 / Pekko — it does not share the Go toolchain. The etclabscore/core-geth codebase at v1.12.20 was assessed against the go-ethereum GitHub Security Advisory database and the Go vulnerability database (vuln.go.dev). Each advisory was verified for applicability to core-geth's shared codebase and manually ported or cherry-picked where upstream structural differences prevented a clean merge. All patches were validated through Mordor testnet deployment and automated test suites across the Olympia reference client set (Core-Geth, Besu, Nethermind).
References
- ethereumclassic/core-geth — patched v1.13.0
- etclabscore/core-geth — upstream (unmaintained since June 2024)
- Full audit report — docs/audits/2026-03-security-audit.md
- go-ethereum GitHub Security Advisories
- Go Vulnerability Database — vuln.go.dev
- ETC Node Clients
- Olympia Client Implementations
- ECIP-1112: Treasury Funding for Protocol Maintenance