Reproduced Exploit
Sablier / PRBProxy — Plugins can be maliciously overridden by colliding signatures
1. Plugins are installed by mapping each selector from methodList() → plugin address. 2. There is no check that the selector is free; a later install overwrites the earlier plugin. 3. A malicious "fee" plugin lists the same selector as Sablier's onStreamCanceled. 4. On stream cancel, the proxy DELE…
Chain
Other
Category
untagged
Date
Jul 2023
Source
AuditVault
EVM Playground
Source-level debugger — step opcodes and Solidity in sync
The attack is replayed in an in-browser EVM preloaded with the exact dumped fork state. The execution tree shows every call; step by Solidity line or by opcode across all depths — source, Stack, Memory, Storage, Balances (native / ERC-20 / NFT), Transient storage and Return value stay in sync. Click a tree node, opcode, or source line to jump. No backend, no live RPC.
Source & credit. Reproduction of a public audit finding curated by AuditVault — the original finding: 54666-plugins-can-be-maliciously-overridden-by-colliding-signature. Standalone Foundry PoC and full write-up: 54666-plugins-can-be-maliciously-overridden-by-colliding-signature_exp in the
evm-hack-registrymirror.
Vulnerability classes: vuln/wrong-condition · admin-takeover · selector-collision
Reproduction: self-contained Foundry PoC with only
forge-std— no fork. output.txt · test/54666-…_exp.sol.
AuditVault taxonomy: lang/solidity · platform/cantina · severity/high · sector/streaming · genome: wrong-condition · admin-takeover
Key info#
| Impact | HIGH — a colliding plugin silently replaces onStreamCanceled and steals stream refunds from the proxy owner |
| Protocol | Sablier (PRBProxy integration) — PRBProxyAnnex.installPlugin |
| Vulnerable code | plugins[methodList[i]] = plugin with no collision check |
| Bug class | 4-byte selector collision / missing install guard |
| Finding | Cantina — Sablier, July 2023 · #54666 · reporter Zach Obront |
| Report | cantina_sablier_jul2023.pdf |
| Source | AuditVault |
| Fix | Sablier PR 121 — revert on selector collision |
| Compiler | ^0.8.24 (PoC) |
TL;DR#
- Plugins are installed by mapping each selector from
methodList()→ plugin address. - There is no check that the selector is free; a later install overwrites the earlier plugin.
- A malicious "fee" plugin lists the same selector as Sablier's
onStreamCanceled. - On stream cancel, the proxy DELEGATECALLs the malicious plugin, which sends the refund to the attacker instead of the owner.
Diagrams#
Impact#
Theft of cancel refunds (and potentially all refundable stream value once the attacker gains control flow mid-hook).
Sources#
- AuditVault #54666
- Cantina Sablier Jul 2023
- Reduced PRBProxyAnnex.installPlugin from the finding (Sablier PR 121 fixed)
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 54666-plugins-can-be-maliciously-overridden-by-colliding-signature_exp (evm-hack-registry mirror).
- AuditVault finding: 54666-plugins-can-be-maliciously-overridden-by-colliding-signature.
Alerts & third-party analyses
These dashboards index community alerts tweets, post-mortems, and independent write-ups. Reach them through the protocol name above to cross-check this reproduction against other analyses.