Skip to content

fix: add cycle detection to EIP-712 typed data encoding to prevent stack overflow DoS#210

Merged
pkieltyka merged 1 commit into
masterfrom
fix/eip712-cycle-detection
Jun 19, 2026
Merged

fix: add cycle detection to EIP-712 typed data encoding to prevent stack overflow DoS#210
pkieltyka merged 1 commit into
masterfrom
fix/eip712-cycle-detection

Conversation

@patrislav

Copy link
Copy Markdown
Member

Summary

  • Cyclic EIP-712 type definitions (e.g. A→B→A) cause infinite recursion in EncodeType/encodeValue, leading to an unrecoverable stack overflow (recover() cannot catch it — the process dies)
  • Add ValidateTypeGraph() using DFS with grey-node cycle detection, called at two entry points:
    • UnmarshalJSON — rejects malicious payloads before any recursive traversal
    • Encode — catches programmatically constructed cyclic types
  • Array type references (e.g. B[]) are handled by stripping the suffix before graph traversal
  • Valid DAGs (e.g. diamond-shaped type graphs with shared subtypes) continue to work correctly

Test plan

  • Simple cycle: A→B→A (errors)
  • Self-referencing type: A→A (errors)
  • Longer cycle: A→B→C→A (errors)
  • Cycle through array types: A→B[]→A (errors)
  • Valid DAG with diamond shape: A→B, A→C, B→D, C→D (passes)
  • Valid simple types with no custom subtypes (passes)
  • Cycle rejected during JSON unmarshal path (errors)
  • Cycle rejected during Encode/EncodeDigest path (errors)
  • All existing tests pass unchanged

…ack overflow DoS

Cyclic type definitions (e.g. A→B→A) caused infinite recursion in
EncodeType/encodeValue, leading to an unrecoverable stack overflow.
This was reachable via unauthenticated endpoints with a ~200-byte payload.

Add ValidateTypeGraph() with DFS cycle detection, called in both
UnmarshalJSON and Encode to reject cycles before any recursion begins.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@patrislav patrislav requested a review from a team June 19, 2026 11:18

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9608992df0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread ethcoder/typed_data.go
Comment on lines +29 to +30
for typeName := range t {
if err := t.walkTypeGraph(typeName, make(map[string]bool)); err != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate only reachable EIP-712 types

Because this loops over every entry in Types, Encode and JSON unmarshalling now reject cycles that are never reachable from PrimaryType or EIP712Domain. For example, a signable payload with primary type Mail plus an unused A -> B -> A helper definition now fails before encoding, even though the existing encoder only traverses the domain and primary-type dependency graph and the unused types cannot cause recursion. Limit the DFS roots to the types actually encoded so irrelevant definitions do not break otherwise valid typed data.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unreachable types are irrelevant, I don't think we need to make an exception for them. Open to changing this though, if needed.

@pkieltyka pkieltyka merged commit b9c76cc into master Jun 19, 2026
14 checks passed
@pkieltyka pkieltyka deleted the fix/eip712-cycle-detection branch June 19, 2026 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants