Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Auxiliary-info store keeps unbounded data from any unauthenticated peer

Aperta
#652 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@yacovm ci sta già lavorando.

Dal 27/10/2026.

  • #667 di @yacovm — aperta

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
56/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
go

Direzione di ricerca

Read msm/auxiliary.go and instance.go:413-423 to trace how auxiliary messages reach the store and how sender identities relate to the validator set for the next epoch. Review the existing approval checks in msm/approvals.go:54-60 and the epoch setup in instance.go:564-596. Done means messages from nonmembers are dropped, stored entries and bytes are bounded, and entries are removed when no longer usable; the issue also calls for a test covering non-validator identities.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

high security

Details

Any computer that can connect to a Simplex validator, even one that is not a validator, can crash it by running it out of memory. It needs no role, signature or victim action. It sends auxiliary-info messages under many made-up peer identities. The store auxInfoStore.HandleAuxiliaryMessage keeps every one, with no membership check, size cap or eviction.

flowchart TD
  n1["any network peer, not a validator"]
  n2["Instance.handleMessageForEpoch"]
  n3["auxInfoStore.HandleAuxiliaryMessage"]
  n4["validator memory (sentInfo map)"]
  n5["validator-membership check and size cap"]
  n1 -->|"sends auxiliary info under many identities"| n2
  n2 -->|"passes on after epoch check only"| n3
  n3 -->|"stores every entry, never evicts"| n4
  n5 -->|"not applied"| n3
  classDef actor stroke:#2563eb,stroke-width:2px
  classDef vulnerable_code stroke:#dc2626,stroke-width:2px
  classDef existing_control stroke:#16a34a,stroke-width:2px
  classDef missing_control stroke:#dc2626,stroke-width:2px,stroke-dasharray:5 5
  classDef asset stroke:#9333ea,stroke-width:2px
  classDef component stroke:#6b7280,stroke-width:1px
  class n1 actor
  class n2 component
  class n3 vulnerable_code
  class n4 asset
  class n5 missing_control
  1. attacker reads the current epoch number from any block or vote. The epoch number is public. It is the only value the attacker needs to get a message past the gate.
  2. attacker sends an AuxiliaryInfo message of up to about 2 MiB from each of many self-made peer identities. The host's per-message cap, mirrored as DefaultMaxMessageSize, is about 2 MiB. That is the only limit on each message's size. (avalanchego/misc.go:20)
  3. the handler Instance.handleMessageForEpoch passes each message to StateMachine.HandleAuxiliaryInfo after checking only that msg.AuxiliaryInfo.Epoch == i.e.Epoch. The sender is never checked against a validator set, so any peer passes. (instance.go:413-423)
  4. the store auxInfoStore.HandleAuxiliaryMessage writes a.sentInfo[from] = info for every sender. There is no validator-membership check, no cap on the number of senders, no cap on len(info.Data) beyond the host limit, and no eviction. Nothing in the repository deletes from sentInfo. (msm/auxiliary.go:106-112)
  5. the validator keeps all entries until createEpochConfig builds a new StateMachine for the next epoch. The map therefore lives for the whole epoch. Memory held is the number of distinct sender IDs times the message size. (instance.go:564-596)
  6. the validator process runs out of memory and crashes. The attacker can do this to every validator at once, which stalls consensus.

Evidence

  1. msm/auxiliary.go:106–112
  2. instance.go:413–423
  3. msm/auxiliary.go:89–104
  4. msm/approvals.go:54–60
  5. instance.go:564–596
  6. msm/auxiliary.go:115–147
  7. avalanchego/misc.go:20

Impact

The attacker makes a validator's memory grow until the process is killed, and can do this to every validator at once, stalling consensus. No data is disclosed or modified.

Reproduction steps

  1. The attacker is any peer that can connect to a validator and deliver messages to HandleMessage. It does not have to be a validator. It reads the current epoch number from a block or vote, then sends one AuxiliaryInfo message of about 2 MiB from each of many self-made peer identities. Each message passes the epoch check at instance.go:415 and stays in sentInfo until the epoch ends. In the shipped configuration (NoopAuxiliaryInfoApp, whose IsSufficient always returns true) the stored entries are never read, but they are still retained. With a real auxiliary-info application, collectAuxInfo also sorts and runs IsLegalAppend on every stored entry each time the leader builds a block during a transition, so the flood costs CPU as well.

Recommended fix

auxInfoStore.HandleAuxiliaryMessage (msm/auxiliary.go:106-112) keeps state keyed by an unchecked sender identity. It has no membership check, size cap or eviction, so a peer that is not a validator can make the node allocate memory without limit.

Fix criteria: Auxiliary info is kept only from members of the next epoch's validator set, and is dropped otherwise. The number of entries and the total bytes are bounded by a limit derived from the validator-set size and the message cap. Entries are discarded once they can no longer be used. A test sends messages from N non-validator identities and confirms that len(store.sentInfo) stays 0 and heap use does not grow with N.

Status on main

Re-checked against main at 90995e0 on 2026-10-26; still present:

instance.go:413-423 only checks msg.AuxiliaryInfo.Epoch == i.e.Epoch before calling msm.HandleAuxiliaryInfo (msm/msm.go:248-250). auxInfoStore.HandleAuxiliaryMessage (msm/auxiliary.go:106-112) runs a.sentInfo[from] = info with no validator-membership check, no limit on entries or bytes, and no eviction. collectAuxInfo (msm/auxiliary.go:115-147) sorts every stored entry and runs IsLegalAppend on each one. No PR touches this. Open issue #608 is about a different aux-info problem.


Severity: HIGH
Status: Open
Category: Resource exhaustion
CWE: CWE-770
Repository: ava-labs/Simplex
Branch: main
Date created: 2026-10-26
Claude Security finding: https://claude.ai/security/findings/find_01QjhTxds7zdb3mrNDj3fuAa

Lingua principale
Go
Stelle
22
Fork
4
Merge medio
1g 16h
PR unite (30g)
35

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di ava-labs/Simplex

Tutte le issue di ava-labs/Simplex

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.