Share
## https://sploitus.com/exploit?id=D6CE4316-4E63-5E67-9E2D-AF1504A734F0
# @mysten/sui.js TransactionBlock Deserialization PoC

## Summary

A type confusion vulnerability in `@mysten/sui.js` versions `=1.0.0` (note: package was renamed)

The `TransactionBlock` class serializes commands as JSON with symbolic references (`GasCoin`, `Input`, `Result`). The `Pure` input type stores address values as raw byte arrays without binding validation. During deserialization, a modified `Pure` value is accepted without re-verifying that it matches the original intent.

### Attack scenario

1. Attacker crafts a dApp interaction (or malicious WalletConnect session) that presents a `TransactionBlock` showing:
   ```
   SplitCoins(GasCoin, [amount]) โ†’ TransferObjects([coin], victim_address)
   ```

2. The wallet UI renders the human-readable intent: "Send X SUI to yourself"

3. The actual signed transaction has the `Pure` input substituted:
   ```
   TransferObjects([coin], attacker_address)
   ```

4. Because `signAndExecuteTransactionBlock` in `@mysten/dapp-kit` signs the serialized bytes (not the displayed intent), the wallet signs the attacker's version.

### Root cause

In `@mysten/sui.js/transactions`, `TransactionBlock.from()` deserializes without validating:
- Input `Pure` values against their original source
- Address inputs against the declared sender
- `GasCoin` binding consistency across serialize/deserialize boundary

The v1.0 rewrite (`@mysten/sui`) replaced `TransactionBlock` with `Transaction` and uses BCS-native serialization with stricter type validation.

## Impact

- **Affected apps:** Any dApp using `@mysten/sui.js` 0.x with `signAndExecuteTransactionBlock`
- **Attack vector:** Malicious dApp, compromised WalletConnect relay, or MITM on RPC
- **Result:** SUI/token transfer to attacker address while wallet shows legitimate recipient
- **Note:** Hardware wallets that display raw bytes (not parsed intent) are not affected

## Reproduction

```bash
git clone https://github.com/hanyvert/sui-txblock-deser-poc
cd sui-txblock-deser-poc
npm install
npm test          # serialization analysis (offline, no network)
npm run poc       # on-chain tx pattern analysis (read-only, mainnet)
```

### Test output

The test checks three deserialization properties:
1. **Basic roundtrip** โ€” whether serialized inputs remain mutable
2. **Input substitution** โ€” whether address Pure values can be swapped
3. **GasCoin reference** โ€” whether GasCoin symbolic binding is verified

## Fix

Upgrade from `@mysten/sui.js` to `@mysten/sui` >= 1.0:

```bash
npm uninstall @mysten/sui.js
npm install @mysten/sui
```

Migration guide: https://sdk.mystenlabs.com/typescript/migrations/sui-1.0

## Responsible Disclosure

This report is shared privately with affected project maintainers before publication. If you confirm the issue affects your deployment, I'd like to coordinate disclosure timing.

## References

- [@mysten/sui v1.0 migration](https://sdk.mystenlabs.com/typescript/migrations/sui-1.0)
- [Sui TypeScript SDK changelog](https://github.com/MystenLabs/sui/blob/main/sdk/typescript/CHANGELOG.md)
- [BCS serialization spec](https://docs.sui.io/concepts/sui-move-concepts/collections#bcs-serialization)