|
| 1 | +### Security Advisory on Miniscript MinimalIF bug (`d:` wrapper is not `u` ) |
| 2 | + |
| 3 | +_ALl of the affected versions have been yanked_. Users should upgrade to `1.1.0`, |
| 4 | +`2.1.0`, `3.1.0`, `4.1.0`, `5.2.0`, `6.1.0` or `7.0.0`. |
| 5 | + |
| 6 | +Andrew Poelstra recently discovered a vulnerability in miniscript spec that could |
| 7 | +potentially allow miners to steal coins locked in certain miniscript fragments. We |
| 8 | +recommend all users upgrade to the latest miniscript version as soon as possible. |
| 9 | +Details of the vulnerability are mentioned towards the end of the post. |
| 10 | + |
| 11 | +For ease of upgrade, we have released a bug fix release for versions 1.1.0, 2.1.0, |
| 12 | +3.1.0, 4.1.0, 5.2.0, and 6.1.0. All other previous releases have been yanked for |
| 13 | +safety. The miniscript website (bitcoin.sipa.be/miniscript) and compiler have |
| 14 | +been updated so that they no longer produce the vulnerable scripts. |
| 15 | + |
| 16 | +### Details of the vulnerability: |
| 17 | + |
| 18 | +The wrapper `d` (`OP_DUP OP_IF [X] OP_ENDIF`) was incorrectly marked to have the |
| 19 | +`u` property. The `u` property states "When [X] is satisfied, this expression will |
| 20 | +put an exact 1 on the stack (as opposed to any nonzero value)". However, this is |
| 21 | +only true if we have a `MINIMALIF` consensus rule. Unfortunately, this is only a |
| 22 | +policy rule for segwitv0 and p2sh scripts. `MINIMALIF` is a consensus rule since |
| 23 | +the taproot upgrade. |
| 24 | + |
| 25 | +In other words, this vulnerability only affects coins with sh, wsh and shwsh. If |
| 26 | +your coins are under taproot descriptor, you are not vulnerable. |
| 27 | + |
| 28 | +### How can this be exploited? |
| 29 | + |
| 30 | +Certain combinations of `d` wrapper inside `or_c` or `or_d` are innocuous. However, |
| 31 | +when combined with thresh, this could allow miners to steal coins from the threshold |
| 32 | +provided the underlying condition in `d` wrapper is satisfied. |
| 33 | + |
| 34 | +Consider the script `thresh(2, pk(A), s:pk(B), sdv:older(2) )` . Semantically, this |
| 35 | +means that either A and B can spend this before 2 blocks, or after 2 blocks either |
| 36 | +A or B can spend these funds. The `thresh` fragment expects all of its children to |
| 37 | +result in either 1/0 (not any other number). However, a miner could malleate the |
| 38 | +user-provided OP_1 in `d` wrapper to OP_2, setting empty signatures A and B bypassing |
| 39 | +the threshold check. |
| 40 | + |
| 41 | +### How to check if you are affected? |
| 42 | + |
| 43 | +If the latest version of miniscript cannot spend your funds, you could be |
| 44 | +affected. In particular, if you are using a `thresh` construction like above, |
| 45 | +and the timelock has expired, your coins are vulnerable. If the timelock has not |
| 46 | +expired, your funds are not at risk if you move them before the timelock activates. |
| 47 | + |
| 48 | +If you cannot spend funds with the new update, please contact us. We will assist |
| 49 | +you with next steps. |
| 50 | + |
| 51 | +Alekos(@afillini) and Riccardo Casetta scanned the blockchain for all spent outputs since |
| 52 | +the miniscript release to check if there were vulnerable. Fortunately, they could |
| 53 | +not find any funds that were vulnerable. |
| 54 | + |
| 55 | +If you have more questions or need any assistance. Feel free to contact us via IRC or email. |
0 commit comments