Skip to content

security(dpp): prove token config update action_id vote swap vulnerability#3345

Closed
QuantumExplorer wants to merge 1 commit into
v3.1-devfrom
security/token-config-action-id-vote-swap
Closed

security(dpp): prove token config update action_id vote swap vulnerability#3345
QuantumExplorer wants to merge 1 commit into
v3.1-devfrom
security/token-config-action-id-vote-swap

Conversation

@QuantumExplorer
Copy link
Copy Markdown
Member

Security Finding: Token Config Update Action ID Vote Swap

Severity: High
Found by: Codex security audit (finding b8a8320f)

Vulnerability

The action_id for token configuration updates is computed using only the item type index (u8_item_index()), not the actual value. This means two different config updates of the same type produce identical action IDs:

  • MaxSupply(100) and MaxSupply(999_999_999_999)same action_id
  • ManualMinting(NoOne) and ManualMinting(ContractOwner)same action_id

Attack Scenario

  1. Group member proposes MaxSupply(100) (conservative limit)
  2. Other members vote to approve — action_id is hash(... || 4) where 4 = MaxSupply type index
  3. Attacker submits finalization with MaxSupply(999_999_999_999)same action_id since type index is still 4
  4. Drive applies the payload from the transition without verifying it matches the stored group action
  5. Token now has effectively unlimited supply, contrary to what the group voted on

Root Cause

  • v0_methods.rs:83update_token_configuration_item.u8_item_index() strips all value information
  • token_config_update_transition.rs:79-85 — Drive applies update_token_configuration_item from the submitted transition, not from the stored group action

Contrast

TokenMintTransition correctly includes mint_amount in the action_id hash. TokenBurnTransition correctly includes burn_amount. Only TokenConfigUpdateTransition is vulnerable.

This PR

4 proof-of-concept tests demonstrating the vulnerability. No fix included — fix should be in a separate PR.

Recommended Fix

  1. Include the full serialized TokenConfigurationChangeItem in the action_id hash (not just the type index)
  2. As defense-in-depth, validate the submitted config item matches the stored group action on finalization

…ility

The action_id for token config updates is derived from only the item
TYPE INDEX (u8_item_index), not the actual value. This means:
- MaxSupply(100) and MaxSupply(999999999999) produce the SAME action_id
- ManualMinting(NoOne) and ManualMinting(ContractOwner) produce the SAME action_id

Attack: A group member proposes a conservative config change, gets votes
approved, then submits a finalization with a malicious value of the same
type. Drive applies the transition payload without verifying it matches
the stored group action.

Contrast: TokenMintTransition correctly includes the amount in the hash.

4 PoC tests proving the vulnerability, all passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added this to the v3.1.0 milestone Mar 16, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 16, 2026

Warning

Rate limit exceeded

@QuantumExplorer has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 6 minutes and 50 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 099623b3-fd85-4f8c-8e69-d20a8b4e4c27

📥 Commits

Reviewing files that changed from the base of the PR and between 040f1e2 and 5d657f5.

📒 Files selected for processing (1)
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_config_update_transition/v0_methods.rs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch security/token-config-action-id-vote-swap
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 16, 2026

Codecov Report

❌ Patch coverage is 95.50562% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.90%. Comparing base (040f1e2) to head (5d657f5).
⚠️ Report is 10 commits behind head on v3.1-dev.

Files with missing lines Patch % Lines
...ition/token_config_update_transition/v0_methods.rs 95.50% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##           v3.1-dev    #3345   +/-   ##
=========================================
  Coverage     74.90%   74.90%           
=========================================
  Files          3000     3000           
  Lines        271665   271754   +89     
=========================================
+ Hits         203478   203564   +86     
- Misses        68187    68190    +3     
Components Coverage Δ
dpp 62.80% <95.50%> (+0.05%) ⬆️
drive 80.25% <ø> (ø)
drive-abci 85.99% <ø> (ø)
sdk 31.25% <ø> (ø)
dapi-client 79.06% <ø> (ø)
platform-version ∅ <ø> (∅)
platform-value 58.46% <ø> (ø)
platform-wallet 60.40% <ø> (ø)
drive-proof-verifier ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

Well-constructed security PoC demonstrating a real action_id collision vulnerability in TokenConfigUpdateTransition. The 4 tests clearly prove that different config values of the same type produce identical action_ids, enabling vote-swap attacks in multi-party group scenarios. The contrast test against TokenMintTransition effectively shows this is an inconsistency, not a design choice. No production code changes — test-only PR as intended.

Reviewed commit: 5d657f5

@QuantumExplorer
Copy link
Copy Markdown
Member Author

Yes, it will be fixed.

@QuantumExplorer
Copy link
Copy Markdown
Member Author

Closing — this vulnerability is now fixed in PR #3346 which includes the v1 action_id calculation that hashes the full serialized config item payload. The regression test proving the vulnerability exists (and is fixed) is in #3346's test suite (v0_action_id_same_discriminant_different_values_produces_same_id_vulnerability).

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