Core-Geth Security Follow-Up: August 2026¶
- Follows:
2026-03-security-audit.md - Subject:
etclabscore/core-gethv1.12.23 (“Argos”), released 14 August 2026 - Prepared by: The core-geth Authors
- Work carried out by: White B0x
- Method: direct measurement against
etclabscore/core-gethat tagv1.12.23, and against the advisory records at OSV and the GitHub Advisory Database
On this page: What operators need to do · Summary · What v1.12.23 contains · What v1.12.23 does not change · One response cap in v1.12.23 can still reject honest peers · CVE identifier reconciliation · Status of v1.13.0 · Supporting this work · References
What operators need to do¶
Track releases at ethereumclassic/core-geth and upgrade to v1.13.0 or later. Every finding in this document and in the March 2026 audit is resolved there.
v1.12.23 is real security work, and it does not close the two findings that matter most to a node operator:
- The Go toolchains are still Go 1.21 and, for the Arm archives, Go 1.22, twenty-four and eighteen months past end of life. Every node built from any v1.12.x release, including this one, carries whatever runtime vulnerabilities have accumulated since, independent of the client’s own code. Go toolchain lists the standard library advisories.
- The
eth_syncingregression introduced in v1.12.22 is untouched. #697 reportshighestBlockincorrectly against the network head, which misleads exchanges, explorers and monitoring that read it to decide whether a node is synced. - One response cap in this release can disconnect peers that are answering correctly. The release corrects that class of error for account ranges and leaves it in place for storage ranges; see the finding below.
- Its release notes carry no advisory identifiers, like v1.12.21’s, and v1.12.22’s notes attach CVE-2026-26315 to work the records assign to CVE-2026-26314.
The organization that owns the repository has published that it does not expect to continue this work. Its 2024 retrospective states:
“Without any way to obtain funding, the ETC Coop will be in maintenance mode, with spending minimized, until the funding runs out. At that time, it will be up to other stakeholders to take on any required maintenance of the ETC client, unless a new plan materializes.”
v1.13.0 is that continuation, developed in the open at ethereumclassic/core-geth. It carries the Go 1.26 toolchain, every CVE fix, the same p2p hardening series measured here, and the storage-range correction this release does not make.
Summary¶
A third release has been cut at etclabscore/core-geth since the March 2026 audit. v1.12.23 is substantive security work: 32 commits carrying a delayed-decoding hardening series for the p2p protocols, plus seven go-ethereum backports.
Two findings from the March audit are unchanged by it. The client remains on end-of-life Go toolchains: Go 1.21, now 24 months past, and Go 1.22 for the Arm archives, now 18 months past. The eth_syncing regression introduced in v1.12.22 is not addressed.
This document records what v1.12.23 contains, what it leaves open, and where v1.13.0 stands.
What v1.12.23 contains¶
Measured across v1.12.22..v1.12.23: 32 commits, 71 files, +3,036 / -796 lines.
Delayed-decoding series. The release defers decoding of p2p message contents until after the message has been validated, so a peer cannot force allocation proportional to a claimed item count before anything has checked it:
| Commit | Change |
|---|---|
b25f25cf1 | rlp: add RawList for working with un-decoded lists |
887da91c6 | delay block body decoding until content validation |
717942ef3 | delay receipts decoding until content validation |
de544c0c3 | delay transaction packet decoding |
4a2b0effc | delay snap message decoding |
4cdebb034 | delay propagated block decoding until content validation |
4a8cd33ea | discard message before size check |
0f8924182 | validate responses against pending requests in p2p/tracker |
ff7d98f1a | fix crash in p2p/tracker clean when the tracker is stopped |
85ac4d685 | recalibrate snap account-range response item cap |
Upstream backports. Seven changes from go-ethereum: #34787 (stop serving on unavailable responses), #34745 (drop peers sending invalid bodies or receipts), #34870 (batch index in deliver reconstruct), #34976 (snap error message), #33803 (embedded node size validation), #32210 (announcement drop logic), #30918 (prevent hanging dispatch).
The delayed-decoding refactor is adaptable to core-geth. go-ethereum’s rlp.RawList approach does not cherry-pick cleanly onto this codebase (13 merge conflicts), and v1.12.23 shows it can nonetheless be carried across with manual work.
What v1.12.23 does not change¶
The Go toolchains are unchanged and remain end-of-life. Measured at tag v1.12.23:
| Location | Value |
|---|---|
go.mod | go 1.21 |
.github/workflows/test-linux.yml | go-version: '1.21' |
Dockerfile | FROM golang:1.22-alpine |
build/checksums.txt | version:golang 1.22.1 |
The published archives record what built them: go1.21.13 for Linux x86_64, macOS and Windows, and go1.22.1, the build/checksums.txt pin, for every Arm archive. Go 1.21 reached end-of-life in August 2024 and Go 1.22 in February 2025, and neither receives security patches. Every node built from this release inherits whatever unpatched runtime vulnerabilities its toolchain carries, independent of the client’s own code. This was the March audit’s finding and it is unchanged across all three 2026 releases.
The eth_syncing regression is not addressed. Issue #697, introduced in v1.12.22, reports highestBlock as incorrect relative to the network head. No commit in v1.12.22..v1.12.23 touches internal/ethapi/.
The cryptographic fixes from v1.12.21 and v1.12.22 are present and unchanged. Verified at tag: the ECIES public-key validation in GenerateShared, which v1.12.21 added, and the field-boundary check in crypto/secp256k1/curve.go, which v1.12.22 added, are both in place and byte-identical to this project’s own implementation.
Finding: one response cap in v1.12.23 can still reject honest peers¶
v1.12.23 recalibrates the AccountRange item cap and documents why: the previous value rejected honest responses. snapResponseLimits now reads
1 2 3 4 | |
with a comment deriving the AccountRange figure from the request tracker’s byte bound.
StorageRanges is bounded the same way and did not get the same treatment. Reading ServiceGetStorageRangesQuery at that tag, the server appends slots until size >= req.Bytes, with a hardLimit of req.Bytes * (1 + stateLookupSlack) above it. Neither is an item count. A storage slot costs a hash plus its value, so at least 33 bytes on the wire, and a 512 KiB budget therefore admits on the order of 15,900 slots before the byte bound stops the server, against a cap of 10,240.
The two caps that remain item-derived are correct: ByteCodesMsg and TrieNodesMsg are genuinely capped server-side at maxCodeLookups and maxTrieNodeLookups, so those numbers are the honest maximum.
Consequence. A peer answering a large storage-range request with small slots can exceed the cap without doing anything unusual, and is disconnected. This is the failure the AccountRange recalibration was made to fix, in the message type beside it.
This client carries no snap item ceiling at all. A response is matched against the pending request that produced it, in bytes for the two byte-bounded messages and in item count for the other two, so the bound is whatever was actually asked for. That cannot refuse an honest reply, which is the failure a fixed cap produces.
CVE identifier reconciliation¶
The advisory records assign these identifiers, verified against OSV and each fix commit confirmed in a full-history go-ethereum clone:
| Identifier | Issue | Fix commit | First release |
|---|---|---|---|
| CVE-2026-26313 · GHSA-689v-6xwf-5jf3 · GO-2026-4508 | p2p message memory exhaustion (CWE-770) | go-ethereum #33835 | v1.17.0 |
| CVE-2026-26314 · GHSA-2gjw-fg97-vg3r · GO-2026-4507 | secp256k1 coordinate check (CWE-20) | 895a8597c | v1.16.9 |
| CVE-2026-26315 · GHSA-m6j8-rg6r-7mv8 | ECIES public key validation in the RLPx handshake | 46bee92f9 | v1.16.9 |
etclabscore/core-geth labels the secp256k1 issue CVE-2026-26315. That identifier belongs to the ECIES handshake issue. The correct identifier for the coordinate check is CVE-2026-26314. The label appears in commit 46bba8dfc, a doc comment and the Go test function name TestIsOnCurveRejectsCoordinatesAboveP_CVE_2026_26315 in crypto/secp256k1/curve_cve_test.go, the description of PR #696, the published release notes for v1.12.22, and a reply on issue #692. No commit, source file, pull request description or release note there uses CVE-2026-26314; that reply does, giving it to the ECIES fix in v1.12.21. The v1.12.21 and v1.12.23 notes carry no CVE identifiers.
Why this is easy to get wrong, and why it matters. CVE-2026-26313 and CVE-2026-26314 are published under the same title, “Go Ethereum affected by DoS via malicious p2p message”. They are distinguished by CWE class and fix commit, not by their titles. An operator matching advisory identifiers against release notes to decide whether they are exposed will not find CVE-2026-26314 addressed at etclabscore/core-geth, and may conclude it is outstanding when the underlying fix shipped in v1.12.22. Both issues are in fact addressed there.
Status of v1.13.0¶
v1.13.0 is released from ethereumclassic/core-geth, the repository created on 21 December 2024 under the GitHub organization that also hosts the ECIP repository. It is where contributions and release artifacts for this series belong. ETC Cooperative’s 2024 retrospective records that with the organization in maintenance mode, “it will be up to other stakeholders to take on any required maintenance of the ETC client”. Relative to v1.12.23 it carries the Go 1.26 toolchain upgrade and the dependency graph that requires, the six CVE patches with their tests, ETC network tooling, and the p2p hardening series. It is the current release series.
Recommendation for operators is unchanged in direction and updated in target. Nodes on any v1.12.x release should upgrade to v1.13.0 from ethereumclassic/core-geth immediately. v1.12.23 is a safer position than v1.12.20 on both the cryptographic and p2p surfaces, and it does not resolve the toolchain exposure.
Supporting this work¶
This follow-up and the v1.13.0 remediation it reports were carried out by White B0x as unfunded public-goods work for Ethereum Classic. Mining pools, centralized exchanges, issuers of Ethereum Classic financial products, Etchash mining hardware manufacturers and large holders all depend on this client. If your operation relies on Ethereum Classic, please help fund its maintenance. Support this work has the routes: sponsorship on GitHub, an invoiced agreement for organizations, or a direct transfer.
References¶
- v1.12.23 release: https://github.com/etclabscore/core-geth/releases/tag/v1.12.23
- Delayed decoding PR: etclabscore/core-geth!699
eth_syncingregression: etclabscore/core-geth#697- CVE-2026-26313: https://osv.dev/vulnerability/GHSA-689v-6xwf-5jf3
- CVE-2026-26314: https://osv.dev/vulnerability/GHSA-2gjw-fg97-vg3r
- CVE-2026-26315: advisories/GHSA-m6j8-rg6r-7mv8
- go-ethereum v1.16.9 release: https://github.com/ethereum/go-ethereum/releases/tag/v1.16.9
- go-ethereum PR #33835 (delayed decoding): ethereum/go-ethereum!33835
- Go release policy and end-of-life: https://go.dev/doc/devel/release